nginx设置代理

因为业务系统需求,需要对web服务作nginx代理,在不断的尝试过程中,简单总结了一下常见的nginx代理配置。

  1. 最简反向代理配置
    在http节点下,使用upstream配置服务地址,使用server的location配置代理映射。

upstream my_server {
server 10.0.0.2:8080;
keepalive 2000;
}
server {
listen 80;
server_name 10.0.0.1;
client_max_body_size 1024M;

location /my/ {
    proxy_pass http://my_server/;
    proxy_set_header Host $host:$server_port;
}

}
通过该配置,访问nginx地址http://10.0.0.1:80/my的请求会被转发到my_server服务地址http://10.0.0.2:8080/。

需要注意的是,如果按照如下配置:

upstream my_server {
server 10.0.0.2:8080;
keepalive 2000;
}
server {
listen 80;
server_name 10.0.0.1;
client_max_body_size 1024M;

location /my/ {
    proxy_pass http://my_server;
    proxy_set_header Host $host:$server_port;
}

}
那么,访问nginx地址http://10.0.0.1:80/my的请求会被转发到my_server服务地址http://10.0.0.2:8080/my。这是因为proxy_pass参数中如果不包含url的路径,则会将location的pattern识别的路径作为绝对路径。

  1. 重定向报文代理
    即便配置了nginx代理,当服务返回重定向报文时(http code为301或302),会将重定向的目标url地址放入http response报文的header的location字段内。用户浏览器收到重定向报文时,会解析出该字段并作跳转。此时新的请求报文将直接发送给服务地址,而非nginx地址。为了能让nginx拦截此类请求,必须修改重定向报文的location信息。

location /my/ {
proxy_pass http://my_server;
proxy_set_header Host $host:$server_port;

proxy_redirect / /my/;

}
使用proxy_redirect可以修改重定向报文的location字段,例子中会将所有的根路径下的url代理到nginx的/my/路径下返回给用户。比如服务返回的重定向报文的location原始值为/login,那么经过nginx代理后,用户收到的报文的location字段为/my/login。此时,浏览器将会跳转到nginx的/my/login地址进行访问。

需要注意的是,服务返回的重定向报文的location字段有时会填写绝对路径(包含服务的ip/域名和端口),有时候会填写相对路径,此时需要根据实际情况进行甄别。

location /my/ {
proxy_pass http://my_server;
proxy_set_header Host $host:$server_port;

proxy_redirect http://my_server/ http://$host:$server_port/my/;

}
上述配置便是将my_server服务的根路径下的所有路径代理到nginx地址的/my/路径下。当nginx配置只有一个server时,http://$host:$server_port前缀可以省略。

  1. 报文数据替换
    使用nginx代理最牛(dan)逼(sui)的情况就是http响应报文内写死了服务地址或web绝对路径。写死服务地址的情况比较少见,但也偶尔存在。最棘手的是写死了web绝对路径,尤其是绝对路径都没有公共前缀。举个例子来说:

一般的web页面会包含如下类似路径:

/public:用于静态页面资源,如js脚本/public/js,样式表/public/css,图片/public/img等。
/static:和/public类似。
/api:用于后台服务API接口。
/login:用于登录验证。
其他。
对于这样的服务,可能的代理配置如下:

location /my/ {
proxy_pass http://my_server/;
proxy_set_header Host $host:$server_port;

proxy_redirect / /my/;

}
location /login/ {
proxy_pass http://my_server/public;
proxy_set_header Host $host:$server_port;
}
location /public/ {
proxy_pass http://my_server/public;
proxy_set_header Host $host:$server_port;
}
location /api/ {
proxy_pass http://my_server/api;
proxy_set_header Host $host:$server_port;
}
由于web页面或静态资源内写死了类似的绝对路径,那么对于用户来说,通过页面内的链接进行跳转时,都会请求到nginx服务对应的路径上。一旦存在另一个服务也包含类似的路径,也需要nginx进行代理,那么矛盾就出现了:访问nginx的同一个路径下的请求究竟转发给哪一个服务?

要解决这个问题,必须在用户收到报文前,将报文的数据中包含的绝对路径都添加统一的前缀,如/my/public,/my/api,/my/login,这样nginx代理配置则可以简化为:

location /my/ {
proxy_pass http://my_server/;
proxy_set_header Host $host:$server_port;

proxy_redirect / /my/;

}
location /other/ {
proxy_pass http://other_server/;
proxy_set_header Host $host:$server_port;

proxy_redirect / /other/;

}
nginx的ngx_http_sub_module模块提供了类似的报文数据替换功能,该模块默认不会安装,需要在编译nginx时添加–with-http_sub_module参数,或者直接下载nginx的rpm包。

使用sub_filter对数据包进行替换的语法如下:

location /my/ {
proxy_pass http://my_server/;
proxy_set_header Host $host:$server_port;

sub_filter 'href="/' 'href="/my/';
sub_filter 'src="/' 'src="/my/';
sub_filter_types text/html;
sub_filter_once  off;

}
上述配置会将/my/下的所有响应报文内容的href=”/替换为href=”/my,以及src=”/替换为src=”/my,即为所有的绝对路径添加公共前缀。

注意,如果需要配置多个sub_filter,必须保证nginx是1.9.4版本之上的。

  1. 总结
    即便如此,sub_filter也不能解决所有问题。目前流行的js框架都会有自动渲染url的功能,也就是说,很多绝对路径并非写死在静态页面内,也是由js代码框架动态生成的,面对这样的情况,sub_filter也是无能为力了。对于这样的情况,笔者只能由衷地奉劝,还是安静的改代码吧!

php 简单的对称加密

<?php

header("content-type:text/html;charset=utf-8");

/**
*@param $string目标字符串
*@param $key 加密key
*@return string
*/
function encryption($string="",$key="cxphp"){
//str_split把字符串分割到数组中
$strArr = str_split(base64_encode($string));
$strcount = count($strArr);
foreach(str_split($key) as $key=>$value){
$key < $strcount && $strArr[$key].= $value;
return str_replace(array('=','+','/'), array('O0O0O', 'o000o', 'oo00o'), join($strArr));
}
}

/**
*@param $string 解析字符串
*@param $key 揭秘到key
*@return string
*/
function deciphering($string='',$skey='cxphp'){
$strArr = str_split(str_replace(array('O0O0O', 'o000o', 'oo00o'), array('=', '+', '/'), $string), 2);
$strCount = count($strArr);
foreach (str_split($skey) as $key => $value)
$key <= $strCount && @$strArr[$key][1] === $value && $strArr[$key] = $strArr[$key][0];
return base64_decode(join($strArr));
}

$a = encryption('这是我的一条测试数据');
var_dump($a);

$a = '6cLo000oZ5piv5oiR55qE5LiA5p2h5rWL6Ko000oV5pWw5o2u';

$b = deciphering($a);
var_dump($b);

关于开展2020年上海市自然科学研究系列高级职称申报和评审工作的通知

关于开展2020年上海市自然科学研究系列高级职称申报和评审工作的通知
发布日期:2020-07-09
各有关单位:

  为进一步做好本市自然科学研究系列高级职称的评审工作,按照《关于完善本市科技创新领域专业技术职称评聘工作的实施细则》(沪人社专〔2016〕2号)、《关于规范本市专业技术职称申报条件的通知》(沪人社专〔2017〕115号)、《关于深化职称制度改革的实施意见》(沪委办发〔2018〕16号)、《关于深化工程技术人才职称制度改革的指导意见》(人社部发〔2019〕16号)和《关于深化自然科学研究人员职称制度改革的指导意见》(人社部发〔2019〕40号)等有关文件精神,现就2020年组织开展上海市自然科学研究系列高级职称申报和评审工作有关事宜通知如下:

  一、评审机构

  上海市自然科学研究系列高级专业技术职务任职资格评审委员会(以下简称“高评委”),负责本市自然科学研究系列、工程系列和实验系列高级职称评审。

  二、申报专业及范围

  本市从事以下工作的在职专业技术人员。

  (一)计算机与信息技术—包括计算机硬件与软件、网络、通信、多媒体应用、微电子技术、系统集成、信息安全、机电一体化、电子商务技术等。

  评审职务:研究员、副研究员、正高级工程师。

  (二)生物与医药—包括基因工程、细胞工程、蛋白质工程、发酵工程、胚胎工程、新药创新、计划生育、古生物和植物生物学等。

  评审职务:研究员、副研究员、正高级工程师、高级工程师、高级实验师。

  (三)新材料与能源—包括金属和合成材料、无机非金属材料、有机合成材料、材料测试评价共性技术和能源技术研发与应用(常规能源技术、可再生能源技术、节能环保技术)等。

  评审职务:研究员、副研究员、正高级工程师、高级工程师、高级实验师。

  (四)光科技—包括与光科技相关的涉及信息、生命健康、探测照明和能源、先进制造与分析测试、先进材料等。

  评审职务:研究员、副研究员、正高级工程师、高级工程师。

  (五)管理科学和科技管理—包括科技情报与方法、情报手段现代化、知识产权、专利审查和专利代理;科技战略规划制订和执行、战略性科技人才资源策划、科技发展预测和技术预见、科技项目管理、评估;科技投资融资、技术市场、科学技术普及等。

  评审职务:研究员、副研究员、正高级工程师、高级工程师。

  (六)体育科学—包括运动医学、运动生物学、运动训练、运动心理、体育理论、体育科学实验等。

  评审职务:研究员、副研究员、高级实验师。

  (七)卫星通信—包括与卫星通信相关的研发工作。

  评审职务:研究员、副研究员、正高级工程师、高级工程师。

  适时开展生物与医药、新材料与能源、体育科学专业的正高实验师评审工作。

  三、申报条件

  (一)基本条件

  遵守中华人民共和国宪法和法律,恪守职业道德,具有良好的职业操守和敬业精神,热爱本职工作。

  在本市企事业单位和社会组织相应专业技术岗位上工作的在职专业技术人员,至申报截止当日符合以下条件之一的,可以在本评委会申报职称:

  1.具有本市户籍;

  2.持有有效期内的《上海市居住证》;

  3.近2年内在本市累计缴纳社会保险满12个月。

  (二)岗位条件

  具备与所申报职称一致或相近专业,并在相应的专业技术岗位上工作。2020年12月31日前已达退休年龄或已办理退休手续的不接受申报(其中按国家规定办理延长退休手续的除外,但申报时须提供延长退休审批表和近一年社保缴费记录)。

  (三)学历、资历条件

  1.申报研究系列须具备国家认可的相关专业大学本科及以上学历。申报工程系列须具备国家认可的理工类相关专业大学本科及以上学历。申报高级实验师须具备国家认可的理工类相关专业大学专科及以上的学历。

  2.申报人须在低一级任职资格岗位上工作满5年以上(其中:大学专科毕业申报高级实验师须在低一级任职资格岗位上工作满6年以上)。取得博士学位申报副研究员、高级工程师或者高级实验师,需受聘助理研究员、工程师或实验师专业技术职务满2年以上。

  3.对工程技术科技创新业绩突出、成果显著的优秀中青年专业技术人才,具有理工类相关专业大专学历,符合《关于本市开展正高级工程师职称评审工作的通知》(沪人社规〔2018〕21号)文件规定的,可通过“绿色通道”破格申报。对海外高层次留学专业技术人才、民营企业高层次专业技术人才中,符合沪人社专〔2016〕2号文件规定的,可通过“直通车”越级申报。

  4.任职年限计算截止到2020年12月31日。

  (四)论文、著作或技术工作总结条件

  在现专业技术职务任职期间,需提供国内(外)权威机构确认的刊物上公开发表出版的论文、著作(独著或独立译著)或本人撰写的个人技术工作总结等。

  1.申报研究员

  需提供以第一作者(通讯作者)发表的论文、著作三篇(部)及以上。

  2.申报副研究员

  需提供以第一作者(通讯作者)发表的论文、著作两篇(部)及以上。

  3.申报正高级工程师

  低一级职务任职期间,具备下列条件之一:

  (1)取得重大科研创新成果和前沿技术突破、解决重大工程技术难题,具有业内引领作用的代表作。须由两名同行院士对该代表作进行认定推荐,并出具书面鉴定意见。

  (2)需提供以第一作者(通讯作者)身份公开发表本专业论文、著作三篇以上(其中主送论文本人撰写字数不少于3000字,共同作者不超过三人(含申报人)并达到国内本专业先进水平),或独立撰写由本人主持或为主参与的科研项目、生产项目或工程设计项目等的技术工作总结三篇以上(具有较高专业技术水平),每篇字数不少于3000字。

  (3)正式出版(独著或独立译著)10万字以上本专业的高质量、高水平学术论著(不含编著、教材、合著)。

  4.申报高级工程师或高级实验师

  需提供以第一作者(通讯作者)身份公开发表本专业论文、著作二篇以上(其中主送论文本人撰写字数不少于3000字,共同作者不超过三人(含申报人)并达到国内本专业先进水平),或独立撰写由本人主持或为主参与的科研项目、生产项目或工程设计项目等的技术工作总结二篇以上(具有较高专业技术水平),每篇字数不少于3000字。

  5.其他条件

  (1)技术工作总结须简要阐明项目水平,重点说明本人的专业理论水平、专业技术能力、在项目中的作用贡献以及解决的技术难点与难题。须为同行专家和主管部门认可(每篇须提交由两名及以上本专业领域在职正高级专家出具的书面鉴定意见)。可行性研究、立项申请、结题报告以及项目技术报告等不作为个人评审职称的依据。

  (2)各类毕业论文或学位论文不作为专业技术职称申报评审论文。

  (3)高评委办公室对申报人所提交论文或技术工作总结(著作除外),将抽取部分进行重合度检测。除独著(译著)仅需上传封面、目录及封底外(PDF格式,打包成一个文件作为论文附件上传),提交论文的,需上传封面、目录、内容(PDF格式),以及所有论文的WORD版本,并确保与所提交的书面材料完全相同。

  (五)继续教育条件

  专技技术人员继续教育包括公需科目和专业科目。

  1.公需科目

  (1)2020年按90学时考核,其中面授课程为30个学时,在线必修课为15个学时,在线选修课为45个学时。公需科目课程安排和报名事宜,请查询“上海市专业技术人员继续教育网”(http://www.sacee.org.cn/jxjysb/)。

  (2)另外,对2020年前取得的公需科目学分,在五年有效期内可以累计。对通过职称外语、职称计算机应用能力考试且未超过五年期限的,可分别折算为3个公需科目学时。

  2.专业科目

  (1)申报“计算机与信息技术”学科组需完成计算机与信息技术应用6门专业科目的继续教育培训。请登录“上海市工业和信息化人才继续教育”网站(http://edu.sheitc.sh.gov.cn/index.jsp)或“上海市专业技术人员继续教育网”网站(http://www.sacee.org.cn/jxjysb/)查询。

  (2)申报生物与医药专业工程系列的申报人须完成6门专业科目的继续教育培训。其中3门必修课和3门选修课。具体报名事宜,请登录“上海医药职工大学-医药之大-行业资讯里查看”网站(www.yiyaozhida.cn)查询。

  (六)其他注意事项

  1.转系列申报条件

  同级职称转评是指在相同等级的不同系列之间的评审,必须在所转系列岗位上工作满1年以上。转升是指直接在不同系列之间进行高一级职称的评审,必须在所转系列岗位上工作满1年以上,且低一级职称聘任累计须满5年以上。

  2.事业单位申报要求

  事业单位专业技术人员实行缺额申报,缺额推荐意见由所在单位人事部门填写在《高级专业技术职务任职资格评定申报表》的“事业单位岗位情况”栏,并同时加盖上级主管部门或区人社局公章。

  3.考核要求

  近三年年度考核合格及以上。

  4.上一年度评审未通过人员今年申报的,必须符合破格申报条件。破格条件见(沪人社专〔2016〕2号)文件规定。

  5.申报人当年只能申报一个评委会的一个学科,且申报材料真实有效,申报时须在《业绩情况表》个人承诺栏签名承诺。

  6.各用人单位应本着客观、公正、实事求是的原则,如实出具单位意见。凡弄虚作假、虚报谎报材料的人员,一经查实,取消参评资格。对通过弄虚作假、暗箱操作等违纪违规行为取得的高级职称,一律予以撤销。

  四、申报评审程序

  (一)网上申报流程

  进入上海市人力资源和社会保障局(rsj.sh.gov.cn–信息公开–职称专家栏),登录上海市职称服务系统,如实注册用户信息、填写基本资料。逐一填写申报信息并上传相关附件后,生成并打印评定申报表一式3份,并在申报表中的个人承诺栏签名,所在单位核实意见栏写明单位核实意见,经单位负责人签字并加盖单位公章,将此页面扫描上传至单位意见项中。申报正高级工程师需由市各委办局、国有企业(集团)、区完成单位考核提名、系统评议推荐等工作。系统评议推荐通过人员由所在系统填写《申报正高级工程师资格人员考核推荐表》(附件5)的“系统/区考核推荐小组意见”栏。

  对以上申报信息检查无误,点击上报材料提交评委会审核。(请确认上传的附件不含病毒,否则可能导致材料上传不完整而影响评审。按照要求上传的附件材料均应为原件的扫描件(不支持上传压缩文件))。

  (二)网上申报注意事项

  1.“学习经历”栏:学历应从高中填起,同一学历及学位证书请合并后上传到对应的附件中。

  2.“工作业绩”栏。应对参加工作以来所从事的技术工作进行比较全面的总结。

  3.“项目情况”栏:各栏(特别是立项时间、担任角色、经费等)应根据项目情况如实填写,并将相关证明材料(项目立项报告、验收报告、任务书及项目参与人员名单等扫描件)及获奖证书上传至对应的项目后的附件中。项目论证结论填写时必须与验收报告结论相一致,并提供相应证明材料,不得随意填写“国际先进”“国内领先”等申报人的主观结论。

  4.“专利课题”栏:中填写的专利必须是已经授权的专利,处于受理或公示阶段的专利都不作为评审依据,请勿填写。且专利必须提供国家专利局颁发的专利授权证书;需以发明专利进行学历破格者需提供第三方(专利使用方)出具专利应用情况证明。

  5.“论文著作”栏:请提交公开发表论文,同时在附件中上传期刊封面、目录及正文等材料。未发表论文的,请上传相关项目技术总结,并在发表论文名称列中填项目技术总结的名称,附件中上传单位盖章的项目技术总结。

  6.“单位意见”栏。用人单位必须对申报人员的工作经历、业绩、论文、科研项目、近3年考核情况等信息分别明确写明核实意见。

  7.“附件资料”栏:

  (1)低一级职称资格证书、评聘材料清晰扫描件;

  (2)各类职业(执业)资格证书清晰扫描件;

  (3)继续教育证明清晰扫描件;

  (4)外省市人员上传《上海市居住证》或近2年的累计满1年的社保缴纳证明清晰扫描件。

  (5)其它需要提交高评委审阅的材料等。

  (三)材料初审

  网上申报后,高评委办公室将初审申报材料,并形成审核意见。对不符合申报材料要求的退回申报人补充材料,对不符合申报条件要求的不予受理。请申报人及时关注网上审核动态,认真修改。

  (四)材料报送及要求

  审核通过后,会分配受理号,并短信通知申报人按送审材料目录要求将书面申报材料送至材料受理点,未经通知请不要自行前往递交材料。

  提交书面材料具体要求请见《送审材料目录》(附件1)。

  (五)学科组答辩

  通过资格审查的专业技术人员应在相应的专业学科组进行答辩,经学科组评议后提交高评委会评审。

  (六)公示及制证

  高评委会评审结束后,通过评审的人员名单在上海市人力资源和社会保障局网站上公示,公示无异议后制作高级职称电子证书。

  五、申报时间及受理地点

  (一)材料报送时间

  1.网上申报时间:2020年7月15日至2020年8月7日。

  截止2020年8月7日下午17:00网上注册关闭,仍未提交完整申报信息的视为放弃当年申报。

  2.书面材料递送时间另行通知。

  (二)材料受理地点

  钦州路100号1号楼5楼。申报计算机与信息技术专业正高级职称的申报人员,也可将书面材料报送至愚园路546号8号楼207室。

  咨询电话:64838846/51371624/62401993。

  六、评审费用

  (一)申报正高级职称评审费用为1000元人民币;申报副高级职称评审费用为800元人民币。

  (二)评审费用在报送材料时一同交付。

  上海市自然科学研究系列高级专业技术职务任职资格评审委员会

  2020年7月9日

【相关附件】
附件1、送审材料目录.docx
【相关附件】
附件2、业绩情况表.docx
【相关附件】
附件3、业绩汇总表.docx
【相关附件】
附件4、专家推荐意见表.docx
【相关附件】
附件5、申报正高级工程师资格人员考核推荐表.docx
【相关附件】
附件6、在职高级工程师及正高级工程师统计表.docx

Yii2-admin的详细使用教程1

网上很多说用composer安装,但是其实国内的环境和网速大家懂的,所以还是下载安装比较快

1.下载地址:
https://github.com/mdmsoft/yii2-admin/releases

2.解压这个下载的包到vendor/mdm/目录下,如果没有mdm目录就新建一个

3.配置backend/config/main.php

<?php
$params = array_merge(
    require __DIR__ . '/../../common/config/params.php',
    require __DIR__ . '/../../common/config/params-local.php',
    require __DIR__ . '/params.php',
    require __DIR__ . '/params-local.php'
);

return [
    'aliases' => [
        '@mdm/admin' => '@vendor/mdm/yii2-admin-2.11',
        'layout' => 'left-menu',
        // for example: '@mdm/admin' => '@app/extensions/mdm/yii2-admin-2.0.0',
        //...
    ], 
    'id' => 'app-backend',
    'basePath' => dirname(__DIR__),
    'controllerNamespace' => 'backend\controllers',
    'bootstrap' => ['log'],
    'modules' => [],
    'modules' => [
        'admin' => [
            'class' => 'mdm\admin\Module',
            'layout' => 'left-menu',//yii2-admin的导航菜单
        ]

    ],
    'components' => [
        /*'authManager' => [
            'class' => 'yii\rbac\DbManager',//'yii\rbac\PhpManager', // or use 
        ],*/
        'authManager' => [
            'class' => 'yii\rbac\DbManager', // 使用数据库管理配置文件
        ],
        'request' => [
            'csrfParam' => '_csrf-backend',
        ],
        'user' => [
            'identityClass' => 'backend\models\Adminuser',
            'enableAutoLogin' => true,
            'identityCookie' => ['name' => '_identity-backend', 'httpOnly' => true],
        ],
        'session' => [
            // this is the name of the session cookie used for login on the backend
            'name' => 'advanced-backend',
        ],
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
        /*
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
            ],
        ],
        */
    ],
    'as access' => [
        'class' => 'mdm\admin\components\AccessControl',
        'allowActions' => [
            'site/*',
            'admin/*',
            'some-controller/some-action',
            // The actions listed here will be allowed to everyone including guests.
            // So, 'admin/*' should not appear here in the production, of course.
            // But in the earlier stages of your development, you may probably want to
            // add a lot of actions here until you finally completed setting up rbac,
            // otherwise you may not even take a first step.
        ]
    ],
    'params' => $params,
];

4.配置common/config/main.php

<?php
return [
    'aliases' => [
        '@bower' => '@vendor/bower-asset',
        '@npm'   => '@vendor/npm-asset',
    ],
    'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
    'components' => [
        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
        'authManager' => [
            'class' => 'yii\rbac\DbManager', // 使用数据库管理配置文件
        ],
    ],
];

5.创建相应的数据库表
在控制台中输入以下命令:

yii migrate --migrationPath=migrations
yii migrate --migrationPath=@yii/rbac/migrations
安装到此完成。
访问http#//localhost/path/to/index.php?r=admin可以看到yii2-admin的管理界面

6.配置访问权限示例
以节点terms(一个自定义的节点)为例,节点terms下共有index,view,create,update,delete五个子节点。
配置目标:
未登录用户仅能访问index节点
一般登录用户能访问index,view,create三个节点
管理员能访问所有节点

步骤一:添加可分配列表

打开yii2-admin路由列表页,点击可用输入框后面的刷新图标将列出当前网站所有可用的路由列表,选中terms各节点路由表添加至右侧可分配路由列表中。

步骤二:添加权限

权限列表=>新增权限,填好名称提交后,添加对应的路由规则即可。
可用列表中除了路由列表还有已经添加了的权限列表,一个权限可以包含另一个权限。

步骤三:添加角色

角色列表=》新增角色,分别添加管理员、一般用户、未登录用户,将对应的权限分配给角色。

步骤四:分配角色

分配界面列出来的用户名是当前系统中已注册的用户。现注册了admin和user账号用于演示。
点击账号后边的眼睛图案,进行权限分配。
按需要,给予相应的权限。

步骤五:配置网站默认访问权限

上面四步配置完成后,我们访问terms各节点测试结果:
以一般用户身份登录时,可以浏览、添加信息,要更新、删除信息时会提示无权操作。符合预期。

以管理员身份登录时,可进行所有操作。符合预期。
但是如果不登录,在访问terms首页时会跳转到登录页面。预期结果是未登录时能访问terms首页。
就是说当前系统默认不认可我们配置给未登录用户的权限。
只需要在配置文件中加一行指定默认规则的代码即可:

    'authManager'=> [
        'class' => 'yii\rbac\DbManager',
        'defaultRoles' => ['未登录用户'],//添加此行代码,指定默认规则为 '未登录用户'
    ],

未登录时再访问terms/index节点就能正常显示了,点别的操作时会跳到登录页面,因为未登录时仅有访问首页的权限。

除了在authManager中配置默认权限,在as access中也可以配置允许所有人访问的节点。

'as access' => [
    'allowActions' => [//下面列出的节点,所有人都可以访问,针对未登录用户的配置也可以移至这里
        'admin/*',
        'site/*',
        ]
]

参考链接:
https://www.kancloud.cn/curder/yii/247759
https://www.yiichina.com/tutorial/571

如何将oracle语句转换成mysql语句

https://blog.csdn.net/qq_41622282/article/details/99689319?utm_medium=distribute.pc_relevant.none-task-blog-title-2&spm=1001.2101.3001.4242

MAC中安装oracle11g,并导入数据

参考出处https://blog.csdn.net/qq_38380025/article/details/80647620
https://blog.csdn.net/qq_34928194/article/details/103536736
使用docker,如果网速好的话,从开始动手到可以使用大概也不用20分钟。

安装步骤如下:

1、安装docker

文件下载:下载docker

2、安装oracle

在终端中执行:

docker pull registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g
下载完成后,启动镜像为容器:

docker run -h “oracle” –name “oracle” -d -p 49160:22 -p 49161:1521 -p 49162:8080 alexeiled/docker-oracle-xe-11g
执行成功后,可使用数据库连接工具进行访问:

默认用户是system,密码oracle。当然一般的做法是创建一个普通用户,使用这个用户进行操作。

3、创建用户

   在终端中执行以下命令进入容器:

docker exec -it 806ebe7f5231 /bin/bash
其中806ebe7f5231是容器id,可使用如下命令获得:

docker ps

进入容器后,使用如下命令登录:

sqlplus system/oracle
然后再创建用户,授权等。

4、导入数据

创建用户、表空间成功后,下一步就要导入数据。

注意:先要将数据库备份文件复制到容器中才能导入。

退出oracle连接后,使用root在容器中创建一个目录,用于放置数据库文件:

mkdir dbfile
exit退出容器,在终端中执行命令,将备份复制到容器:
sudo docker cp /Users/xxx/Desktop/backup.dbf bf939e7c2bd8:/dbfile
以上命令中,/Users/xxx/Desktop/backup.dbf是数据库备份在mac中的全路径,bf939e7c2bd8是容器id,/dbfile是在容器中的存放目录。

复制完成后,再次进入容器,使用sqlplus连接到数据库,按一般步骤进行imp导入即可。

停止/启动oracle服务:

docker stop oracle
docker start oracle

MySQL导入csv

导入csv文件

使用如下命令:
mysql> load data infile "your csv file path" into table [tablename] fields terminated by ','
注意上面导入文件时,都需要提前建立好与文件内各个段对应好的数据表。并且文件的路径需要使用引号括起来,双引号和单引号都可以。

mysql去重的最方便的方法

方法一:

在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其原因是 distinct只能返回它的目标字段,而无法返回其它字段

下面先来看看例子:

table
id name
1 a
2 b
3 c
4 c
5 b

库结构大概这样,这只是一个简单的例子,实际情况会复杂得多。

比如我想用一条语句查询得到name不重复的所有数据,那就必须使用distinct去掉多余的重复记录。

select distinct name from table
得到的结果是:

name
a
b
c

好像达到效果了,可是,我想要得到的是id值呢?改一下查询语句吧:

select distinct name, id from table

结果会是:

id name
1 a
2 b
3 c
4 c
5 b

distinct怎么没起作用?作用是起了的,不过他同时作用了两个字段,也就是必须得id与name都相同的才会被排除。。。。。。。

我们再改改查询语句:

select id, distinct name from table

很遗憾,除了错误信息你什么也得不到,distinct必须放在开头。难到不能把distinct放到where条件里?能,照样报错。。。。。。。

最终好用的语句如下:

select *, count(distinct name) from table group by name

结果:

id name count(distinct name)
1 a 1
2 b 1
3 c 1

最后一项是多余的,不用管就行了,目的达到。。。。。

哦,对,再顺便说一句,group by 必须放在 order by 和 limit之前,不然会报错。。。。。。。。!OK了

总结语句:select *, count(distinct name) from (select * from table……等嵌套语句) group by name
参考出处:https://blog.csdn.net/djun100/article/details/84473838?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

yii2布局全屏

方法一:
导航栏下面的页面在宽屏上不留白的办法
修改views/layouts/main.php
将class=”container” 改成class=”container-fluid”
方法二:

<?php

/* @var $this yii\web\View */

$this->title = '企业画像123';
?>
<style>


.mydivstyle{ border-style:solid; border-width:1px; border-color:#000;width: 1s50px;height:100px;
  background:#000066;

}
h2{
color:#ffffcc;
}
//图片与div同缩放
#testfullscreen{
    background-image: url(img/bg.png);
    background-repeat: no-repeat;
    background-size: 100% 100%;
}


</style>

<script>
function showFull(){
               var full=document.getElementById("testfullscreen");
               launchIntoFullscreen(full);
            }

function delFull() {
                exitFullscreen();
            }
//全屏方法封装:
            function launchIntoFullscreen(element) {
                if(element.requestFullscreen){
                    element.requestFullscreen();
                }
                else if(element.mozRequestFullScreen) {
                    element.mozRequestFullScreen();
                }
                else if(element.webkitRequestFullscreen) {
                    element.webkitRequestFullscreen();
                }
                else if(element.msRequestFullscreen) {
                    element.msRequestFullscreen();
                }
            }
            //退出全屏
            function exitFullscreen() {
                if(document.exitFullscreen) {
                    document.exitFullscreen();
                } else if(document.mozCancelFullScreen) {
                    document.mozCancelFullScreen();
                } else if(document.webkitExitFullscreen) {
                    document.webkitExitFullscreen();
                }
            }
</script>

<div class="site-index">



    <div class="body-content" id="testfullscreen">
    <button  onclick="showFull();">
                全屏
            </button>
<button  onclick="delFull();">
                退出全屏
            </button>
<div class="row clearfix">
        <div class="col-md-4 column">

                            <div class="row-lg-4">
                                <h2>0</h2>
                                <h2>企业高管信息</h2>

                               <div id="main" class="mydivstyle"></div> 
                                <p><a class="btn btn-default" href="http://localhost/index.php?r=site%2Fabout">更多»</a></p>
                            </div>
                            <div class="row-lg-4">
                                <h2>0</h2>
                                <h2>企业综合信息</h2>

                                <div id="m2" class="mydivstyle"></div>
                               <p><a class="btn btn-default" href="http://localhost/index.php?r=site%2Fabout">更多»</a></p>
                            </div>
                            <div class="row-lg-4">
                                <h2>0</h2>
                                <h2>企业图谱</h2>

                                <div id="m3" class="mydivstyle"></div>
                                <p><a class="btn btn-default" href="http://localhost/index.php?r=site%2Fabout">更多»</a></p>
                            </div>
                        </div>
        </div>
        <div class="col-md-4 column">
        </div>
        <div class="col-md-4 column">
        </div>
</div>









    </div>
</div>

<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js">
</script>

<script language="javascript">
$('#aa').load("data.txt");
</script>


       <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
       <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-gl/dist/echarts-gl.min.js"></script>
       <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-stat/dist/ecStat.min.js"></script>
       <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/extension/dataTool.min.js"></script>
       <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/map/js/china.js"></script>
       <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/map/js/world.js"></script>
       <script type="text/javascript" src="https://api.map.baidu.com/getscript?v=2.0&ak=BAfb9bb97f7b712e5426859ac957c98f"></script>
       <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/extension/bmap.min.js"></script>


<!--script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script-->

<script type="text/javascript">
var dom = document.getElementById("main");
var myChart = echarts.init(dom);
var app = {};
option = null;
myChart.showLoading();
$.get('http://localhost/data.txt', function (data) {

    myChart.hideLoading();

    echarts.util.each(data.children, function (datum, index) {
        index % 2 === 0 && (datum.collapsed = true);
    });

  /* myChart.setOption(option = {
        tooltip: {
          //  trigger: 'item',
           // triggerOn: 'mousemove'
        },
        series: [
            {
                type: 'tree',

                data: [data1],

               s top: '1%',
                left: '7%',
                bottom: '1%',
                right: '20%',

               symbolSize: 7,

                label: {
                    position: 'left',
                    verticalAlign: 'middle',
                    align: 'right',
                    fontSize: 9
                },

                leaves: {
                    label: {
                        position: 'right',
                        verticalAlign: 'middle',
                        align: 'left'
                    }
                },

                expandAndCollapse: true,
               // animationDuration: 550,
                //animationDurationUpdate: 750
            }
        ]
    });*/
      myChart.setOption({
         tooltip: {
            trigger: 'item',
            triggerOn: 'mousemove'
        },
    series : 
    [
        {
           "name": "国资委",
           "type": "tree", 
           top: '1%',
                left: '7%',
                bottom: '1%',
                right: '30%',
                 symbolSize: 10,
                 label: {
                    position: 'left',
                    verticalAlign: 'middle',
                    align: 'right',
                    fontSize: 10
                },leaves: {
                    label: {
                        position: 'right',
                        verticalAlign: 'middle',
                        align: 'left'
                    }
                },
           'data':[
                {
                  "id": "000000000",
                  "parentId": null,
                  "name": "国资委",
                  "dataId": null,
                  "companyCount": 782,
                  "children": [{
                      "id": "73746554X9",
                      "parentId": "000000000",
                      "name": "上海同盛投资(集团)有限公司(集团汇总表)",
                      "dataId": "09a30b23-6ff2-4f9b-8d32-f4ac3f8529db",
                      "companyCount": 9,
                      "children": [{
                          "id": "7672369670",
                          "parentId": "73746554X9",
                          "name": "上海同盛置业有限公司(单户表)",
                          "dataId": "03621932-9a7d-4001-aabe-1443541daecd",
                          "companyCount": 0,
                          "children": [
                            {
            "id": "7377674250",
            "parentId": "73746554X9",
            "name": "洋山同盛港口建设有限公司(单户表)",
            "dataId": "459c3698-0bc0-4869-8b9f-df45a1efa9c2",
            "companyCount": 0,
            "children": [{
            "id": "7377674250",
            "parentId": "73746554X9",
            "name": "洋山同盛港口建设有限公司(单户表)",
            "dataId": "459c3698-0bc0-4869-8b9f-df45a1efa9c2",
            "companyCount": 0,
            "children": [{
            "id": "7377674250",
            "parentId": "73746554X9",
            "name": "洋山同盛港口建设有限公司(单户表)",
            "dataId": "459c3698-0bc0-4869-8b9f-df45a1efa9c2",
            "companyCount": 0,
            "children": [{
            "id": "7377674250",
            "parentId": "73746554X9",
            "name": "洋山同盛港口建设有限公司(单户表)",
            "dataId": "459c3698-0bc0-4869-8b9f-df45a1efa9c2",
            "companyCount": 0,
            "children": []
        }]
        }]
        }]
        }

                          ]
                      }, {
            "id": "7844456480",
            "parentId": "73746554X9",
            "name": "洋山同盛联合投资发展有限公司(单户表)",
            "dataId": "3f127dff-efc2-4aa1-93f7-2fbc1c85c388",
            "companyCount": 0,
            "children": []
        }, {
            "id": "7377674250",
            "parentId": "73746554X9",
            "name": "洋山同盛港口建设有限公司(单户表)",
            "dataId": "459c3698-0bc0-4869-8b9f-df45a1efa9c2",
            "companyCount": 0,
            "children": []
        }, {
            "id": "73746554X0",
            "parentId": "73746554X9",
            "name": "上海同盛投资(集团)有限公司(单户表)",
            "dataId": "46e1c2b8-034a-461f-a719-777b2997b955",
            "companyCount": 0,
            "children": []
        }, {
            "id": "73746554X1",
            "parentId": "73746554X9",
            "name": "上海同盛投资(集团)有限公司(集团差额表)",
            "dataId": "5766e8f8-1cac-4143-8de9-f5653ceeddbb",
            "companyCount": 0,
            "children": []
        }, {
            "id": "7605970730",
            "parentId": "73746554X9",
            "name": "上海同盛电力有限公司(单户表)",
            "dataId": "5ef32ea1-785c-4b9f-830b-3f8152d5f715",
            "companyCount": 0,
            "children": []
        }, {
            "id": "7595844510",
            "parentId": "73746554X9",
            "name": "上海同盛投资集团资产管理有限公司(单户表)",
            "dataId": "64073d4d-ed15-4ab9-9620-9030b8fd11b1",
            "companyCount": 0,
            "children": []
        }, {
            "id": "7655620720",
            "parentId": "73746554X9",
            "name": "上海同盛水务有限公司(单户表)",
            "dataId": "6f3b9252-5656-4ff7-8f96-39879caee530",
            "companyCount": 0,
            "children": []
        }, {
            "id": "1345456470",
            "parentId": "73746554X9",
            "name": "上海同盛投资集团房地产有限公司(单户表)",
            "dataId": "8b5e06f8-4dbc-41f4-8896-e1874b509853",
            "companyCount": 0,
            "children": []
        }]
                    }]
                  }
           ]
        }
    ]
});



});
if (option && typeof option === "object") {
    myChart.setOption(option, true);
}
       </script>

d3.js自定义组件

<html>
    <head>
        <meta charset="utf-8">
        <!--script type="text/javascript" src="https://d3js.org/d3.v6.min.js"></script-->
        <script type="text/javascript" src="d3.js"></script>
        <script type="text/javascript" src="demo2.js?r=12s"></script>
    </head>
    <body onload="demo2()">
        <svg id="sticker" width="600" height="300" style="background: lightgrey"/>
            <p>hello,today is a good day!</p>
    </body>
</html>
function sticker(sel,label){
    sel.append("rect").attr("rx",5).attr("ry",5)
    .attr("width",70).attr("height",30)
.attr("x",-35).attr("y",-15)
.attr("fill","none").attr("stroke","blue")
.classed("frame",true);

sel.append("text").attr("x",0).attr("y",5)
.attr("text-anchor","middle")
.attr("font-family","sans-serif").attr("font-size",14)
.classed("label",true)
.text(label?label:d=>d);
    }

function demo2()
{
    var labels=["hello","world"];
var scX=d3.scaleLinear().domain([0,labels.length-1]).range([100,500]);
var scY = d3.scaleLinear().domain([0,labels.length-1]).range([50,150]);
d3.select("#sticker")
.selectAll("g").data(labels).enter().append("g")
.attr("transform",(d,i)=>"translate("+scX(i)+","+scY(i)+")")
.call(sticker);

d3.select("#sticker").append("g")
.attr("transform","translate(175,150)")
.call(sticker,"cool")
.selectAll(".label").attr("fill","red");
}