Apple Script 常用函数

1.读取文件内容返回列表

-- 定义函数,参数为文件路径
on readLinesFromFile(filePath)
	try
		set fileHandler to open for access filePath
		set fileContents to read fileHandler as «class utf8»
		close access fileHandler
		set linesArray to paragraphs of fileContents
		
		return linesArray
	on error errMsg
		try
			close access filePath
		end try
		display dialog "发生错误:" & errMsg buttons {"OK"} default button "OK"
		return {}
	end try
end readLinesFromFile

2.解析json字符串为对象

set JSONString to "[{  \"name\": \"AppleScript\", \"type\": \"Scripting Language\",\"see also\": [ \"Hypercard\"] },{ \"name\": \"JavaScript\",\"type\": \"Prototype Based\", \"see also\": [\"ECMAScript\", \"Python\"] } ]"
set applescriptValue to run script (do shell script ("echo " & JSONString's quoted form & " | sed -E 's/\"([^\"]+)\"[[:space:]]*:[[:space:]]*/|\\1|:/g' | tr -d '\\n\\r'"))
log applescriptValue

3.Apple Script 发送get数据

on HttpGET(getUrl, getData, headers)
	set curlCommand to "curl -X GET"
	set isJsonRequest to false
	if (count of headers) is not 0 then
		repeat with myRecord in headers
			set curlCommand to curlCommand & " -H " & quoted form of (name of myRecord & ": " & value of myRecord)
			if name of myRecord is "Content-Type" and value of myRecord is "application/json" then
				set isJsonRequest to true
			end if
		end repeat
	end if
	if (count of getData) is not 0 then
		set getDataString to ""
		repeat with myRecord in getData
			if isJsonRequest then
				set getDataString to getDataString & "\"" & name of myRecord & "\":\"" & value of myRecord & "\","
			else
				set getDataString to getDataString & name of myRecord & "=" & value of myRecord & "&"
			end if
		end repeat
		if isJsonRequest then
			set getDataString to "{" & text 1 thru -2 of getDataString & "}"
			set curlCommand to curlCommand & " --data-raw " & quoted form of getDataString
			
		else
			set curlCommand to curlCommand & " -d " & quoted form of text 1 thru -2 of getDataString -- 移除末尾的多余的 "&"
		end if
	end if
	set curlCommand to curlCommand & " " & quoted form of getUrl
	set response to do shell script curlCommand
	if isJsonRequest then
		return run script (do shell script ("echo " & response's quoted form & " | sed -E 's/\"([^\"]+)\"[[:space:]]*:[[:space:]]*/|\\1|:/g' | tr -d '\\n\\r'"))
	else
		return response
	end if
end HttpGET

3.Apple Script 发送psot数据

on httpPost(postUrl, postData, headers)
	set curlCommand to "curl -X POST"
	set isJsonRequest to false
	if (count of headers) is not 0 then
		repeat with myRecord in headers
			set curlCommand to curlCommand & " -H " & quoted form of (name of myRecord & ": " & value of myRecord)
			if name of myRecord is "Content-Type" and value of myRecord is "application/json" then
				set isJsonRequest to true
			end if
		end repeat
	end if
	if (count of postData) is not 0 then
		set postDataString to ""
		repeat with myRecord in postData
			if isJsonRequest then
				set postDataString to postDataString & "\"" & name of myRecord & "\":\"" & value of myRecord & "\","
			else
				set postDataString to postDataString & name of myRecord & "=" & value of myRecord & "&"
			end if
		end repeat
		if isJsonRequest then
			set postDataString to "{" & text 1 thru -2 of postDataString & "}"
			set curlCommand to curlCommand & " --data-raw " & quoted form of postDataString
		else
			set curlCommand to curlCommand & " -d " & quoted form of text 1 thru -2 of postDataString -- 移除末尾的多余的 "&"
		end if
	end if
	set curlCommand to curlCommand & " " & quoted form of postUrl
	set response to do shell script curlCommand
	
	if isJsonRequest then
		return run script (do shell script ("echo " & response's quoted form & " | sed -E 's/\"([^\"]+)\"[[:space:]]*:[[:space:]]*/|\\1|:/g' | tr -d '\\n\\r'"))
	else
		return response
	end if
end httpPost
Posted in apple script | Leave a comment

ubuntu 18.04 搭建wordress(LAMP)

#!/bin/bash

# +----------------------------------------------------------------------
# |ubuntu 18.04 LAMP 环境搭建
# +----------------------------------------------------------------------

sudo chmod 777 /root


while getopts "d:p:n:w:" opt; do
  case $opt in
    d)
      domain=$OPTARG
      ;;
    p)
      path=$OPTARG
      ;;
    n)
      dbname=$OPTARG
      ;;
    w)
      password=$OPTARG
      ;;
    \?)
      echo "无效的选项:-$OPTARG"
      exit 1
      ;;
  esac
done

# 检查参数是否缺失
if [ -z "$domain" ] || [ -z "$path" ] || [ -z "$dbname" ] || [ -z "$password" ]; then
  echo "缺少参数,请输入以下参数值: "
  # 检查并要求输入缺失的参数
  if [ -z "$domain" ]; then
    read -p "-d 域名: " domain
  fi

  if [ -z "$path" ]; then
    read -p "-p 路径: " path
  fi

  if [ -z "$dbname" ]; then
    read -p "-n 数据库名: " dbname
  fi

  if [ -z "$password" ]; then
    read -p "-w 密码: " password
  fi
fi



echo "+----------------------------------------------------------------------"
echo "| ubuntu 18.04 LAMP 环境搭建"
echo "+----------------------------------------------------------------------"
echo "| 域名: $domain"
echo "| 路径: $path"
echo "| 数据库名: $dbname"
echo "| 密码: $password"
echo "+----------------------------------------------------------------------"

netstat -tln
netstat -tln | grep 80
read

sudo apt-get update


sudo apt-get install apache2 -y

sudo apt-get install php7.2 libapache2-mod-php7.2 -y
sudo apt-get install mysql-server-5.7 -y
sudo apt install redis-server -y
#sudo systemctl status redis-server
sudo systemctl enable redis-server

# php拓展自行选择按
sudo apt-get install php7.2-fpm php7.2-mysql php7.2-gd php7.2-mbstring   -y
sudo apt-get install php7.2-xml php7.2-curl php7.2-redis php7.2-opcache   -y
sudo apt-get install   php7.2-intl php7.2-zip php7.2-dom php7.2-imagick -y
#sudo apt-get install php7.2-ssh2 php7.2-bcmath php7.2-odbc php7.2-imagick php7.2-imap -y


#sudo apt-get install php7.4 libapache2-mod-php7.4 -y#sudo apt-get install php7.2-redis -y
#sudo apt-get install php7.4-fpm php7.4-mysql php7.4-gd php7.4-mbstring   -y
#sudo apt-get install php7.4-xml php7.4-curl php7.4-redis php7.7-opcache   -y
#sudo apt-get install php7.4-mysql php7.4-intl php7.4-zip  -y
#sudo apt-get install php7.4-ssh2 php7.4-bcmath php7.4-odbc php7.4-imagick php7.4-imap -y

sudo apt-get install zip  -y
sudo a2enmod rewrite
sudo apt-get install wget -y
sudo apt-get install expect -y

read
clear
echo "拓展安装完毕"


host=$(cat <<EOF
<VirtualHost *:80>
    DocumentRoot ${path}
    ServerAlias ${domain}
    ErrorLog \${APACHE_LOG_DIR}/error.log
    CustomLog \${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
EOF
)


sudo touch "/etc/apache2/sites-available/${domain}.conf"
echo "${host}" > "/etc/apache2/sites-available/${domain}.conf"
sudo ln -s "/etc/apache2/sites-available/${domain}.conf" "/etc/apache2/sites-enabled/${domain}.conf"

sudo /etc/init.d/apache2 restart
read
clear
echo "站点配置完毕"
expect_str=$(cat <<EOF
#!/usr/bin/expect

spawn sudo mysql_secure_installation
set password [ lindex $argv 0 ]
expect {
  "*setup VALIDATE PASSWORD plugin*" {
    send "No\r";
    expect {
      "*New password:" {
        send "$password \r";
        expect {
          "Re-enter new password:" {
            send "$password \r";
            expect {
              "*Remove anonymous users?*" {
                send "Y\r";
                expect {
                  "Disallow root login remotely?" {
                    send "No\r"
                    expect {
                      "Remove test database and access to it?" {
                        send "Y\r";
                        expect {
                          "Reload privilege tables now?" {
                            send "Y\r";
                            expect {
                              "All done!" {
                                interact;
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
EOF
)

cd /root
sudo touch "mysql.sh"
echo "${expect_str}" >> "mysql.sh"
sudo chmod +x mysql.sh
sudo expect mysql.sh
sudo rm mysql.sh

sudo /etc/init.d/mysql restart

create_str=$(cat <<EOF
#!/usr/bin/expect

spawn sudo mysql -uroot -p
expect {
  "*password*" {
    send "${password}\r"
    expect {
      "*mysql>*" {
        send "CREATE database ${dbname};\r"
        expect {
          "Query OK" {
            send "CREATE USER \"${dbname}\"@\"localhost\" IDENTIFIED BY \"${password}\";\r";
            expect {
              "Query OK" {
                send "GRANT ALL PRIVILEGES ON *.* TO \"${dbname}\"@\"localhost\";\r";
                expect {
                  "Query OK" {
                    send "FLUSH PRIVILEGES;\r";
                    expect {
                      "Query OK" {
                        send "exit;\r";
                        interact;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
EOF
)

sudo touch "create.sh"
echo "${create_str}" >> "create.sh"
sudo chmod +x create.sh
sudo expect create.sh "$dbname"
sudo rm create.sh
sudo /etc/init.d/mysql restart
read
clear
echo "数据库创建完毕"



sudo sed -i 's/AllowOverride\s*None/AllowOverride All/g' /etc/apache2/apache2.conf
sudo /etc/init.d/apache2 restart

sudo wget https://cn.wordpress.org/latest-zh_CN.zip -P /var/www/html
sudo unzip "/var/www/html/latest-zh_CN.zip" -d /var/www/html
sudo rm "/var/www/html/latest-zh_CN.zip"
sudo touch "$path/.htaccess"
sudo chmod -R 777 "$path/.htaccess"
sudo chmod -R 777 "$path/wp-content/uploads"
sudo rm -R /root/install.sh
Posted in Linux | Leave a comment

Node.js 爬电影天堂种子

封装爬虫模块index.js

const puppeteer = require("puppeteer");
function timeout() {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 2000);
  });
}
module.exports = async (url,callback) => {
    //打开浏览器chrome 路由
    const browser = await puppeteer.launch({
      executablePath: "/Applications/Google\ Chrome.app/"+
        "Contents/MacOS/Google\ Chrome",
        headless: "new" // 添加这一行
    });
    // 创建自页面
    const page = await browser.newPage();
    // 打开一个网页
    await page.goto(url, {
        waitUtil: "networkidle2"
    });
    await timeout();
    // 在页面中执行js
    let results = await page.evaluate(callback);
    // 关闭Chrome
    await browser.close();
    // 返货js执行结构
    return results;
}

爬去数据

const puppeteer = require("./index")
const { SingleBar, Presets } = require('cli-progress');
const fs = require('fs');
function timeout() {
   return new Promise((resolve, reject) => {
      setTimeout(resolve, 3000);
   });
}
const url ='https://www.ygdy8.net/html/gndy/china/index.html'
// 获取首页内容
const result = puppeteer(url, () => {
   let ul = document.querySelectorAll("a[class='ulink']");
   let result = [];
   for (let i = 0; i <= ul.length - 1; i++) {
      let url = ul[i].href
      let name = ul[i].text
      result.push({name:name,url:url});
   }
   return result;
}).then((res)=>{
//获取电影的名字和链接
   let data =[];
   if(res.length >=2){
      let n =1;
      if(res.length % 2 ==0){
         n =res.length/2
      }else{
         n = res.length -1/2
      }
      let data =[];
      for (let i=1;i<=n ;i++){
         let categorize = res[(i-1)*2].name ||"";
         let categorizeUrl = res[(i-1)*2].url|| "";
         let movieName = res[(i-1)*2+1].name||"";
         let movieUrl = res[(i-1)*2+1].url||"";
         data.push({
            categorize:(categorize.match(/\[(.*?)\]/g)[0])
                .replace(/\[|\]/g, ""),
            categorizeUrl:categorizeUrl,
            movieName:(movieName.match(/《(.*?)》/g)[0])
                .replace(/《|》/g, ""),
            movieUrl:movieUrl
         })
      }
      return data
   }
}).then(async res=>{
// 打开每一页获取bt链接
   if(res.length>0){
      const progressBar = new SingleBar({}, Presets.shades_classic);
      progressBar.start(res.length, 0);
      for (let i =0;i<=res.length-1;i++){
         await new Promise(resolve => setTimeout(resolve, 3000));
         let result= await puppeteer(
             res[i].movieUrl,()=>{
            if(res.length>0){
      const progressBar = new SingleBar({}, Presets.shades_classic);
      progressBar.start(res.length, 0);
      for (let i =0;i<=res.length-1;i++){
         await new Promise(resolve => setTimeout(resolve, 3000));
         let result= await puppeteer(res[i].movieUrl,()=>{
            return {
               bt:document.querySelector("a[href^='magnet:']").
                   getAttribute('href')||"",
               img:document.querySelector('#Zoom img').getAttribute('src')||''
            };
         });
         res[i].bt =result.bt;
         res[i].img =result.img;
         progressBar.update(i + 1);
      }
      progressBar.stop();
      return res;
   }else{
      console.log('没有获取到列表')
      process.exit()
   }
            }
         });
         res[i].bt =result;
         progressBar.update(i + 1);
      }
      progressBar.stop();
      return res;
   }else{
      console.log('没有获取到列表')
      process.exit()
   }
}).then(res=>{
   fs.writeFile(
       './data.json', 
       JSON.stringify(res,null, 4), (err) => {
         if (err) throw err;
         console.log('Data written to file');
   });
});
Posted in node.js | Leave a comment

js常用正则验证器

用法

import validator from "/validator.js"
let result = validator.validator(['ip'],"123.56.7.206")
if(result){
  console.log("验证通过");
}else{
  console.log(validator.errors);
}
export default {
  // 手机号
  phone: {
    pattern: new RegExp(/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/, 'g'),
    message: '手机号码格式不正确'
  },
  // ip验证
  ip: {
    pattern: new RegExp(/^91\d{2}|2[0-4]\d|25[0-5][1-9]\d|[1-9](\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)){3}$/, 'g'),
    message: '请输入正确的IP地址'
  },
  requiredEnd: {
    pattern: new RegExp(/^\S*$/, 'g'),
    message: '结尾不能有空格'
  },
  required: {
    pattern: new RegExp(/\s+/, 'g'),
    message: '不能有空格'
  },
  requiredBegin: {
    pattern: new RegExp(/^\S+/, 'g'),
    message: '开头不能有空格'
  },
  // 密码
  password: {
    pattern: new RegExp(
      '^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\\W_!@#$%^&*`~()-+=]+$)(?![a-z0-9]+$)(?![a-z\\W_!@#$%^&*`~()-+=]+$)(?![0-9\\W_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9\\W_!@#$%^&*`()-+=]{7,20}$'
    ),
    message: '密码由6位以上的大小写字母、数字及特殊字符中的3种组合而成',
  },
  // MAC 地址验证
  MAC: {
    pattern: new RegExp(
      /^[A-Fa-f\d]{2}:[A-Fa-f\d]{2}:[A-Fa-f\d]{2}:[A-Fa-f\d]{2}:[A-Fa-f\d]{2}:[A-Fa-f\d]{2}$/
    ),
    message: 'MAC地址格式错误'
  },
  username: {
    pattern: new RegExp(/^[a-zA-Z0-9;',()_./~!@#$%^&*-]{6,10}$/, 'g'),
    message: '名称需要在6-10位,支持数字、字母、英文标点(半角)',
  },
  specialStr: {
    pattern: new RegExp(/^[\u4e00-\u9fa5\a-zA-Z0-9]+$/, 'g'),
    message: '不能有特殊字符',
  },
  // 身份证 验证
  ID: {
    pattern: new RegExp(/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, 'g'),
    message: '身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位可能为数字或字符X',
  },
  // 时间 24:20
  time: {
    pattern: new RegExp(/^(([0-1][0-9])|(^2[0-3])):([0-5][0-9])$/, 'g'),
    message: '请输入正确的时间',
  },
  //纬度
  latitude: {
    pattern: new RegExp(/^-?((0|[1-8]?[0-9]?)(([.][0-9]{1,10})?)|90(([.][0]{1,10})?))$/, 'g'),
    message: '请输入正确的纬度',
  },
  // 经度
  longitude: {
    pattern: new RegExp(/^-?((0|1?[0-8]?[0-9]?)(([.][0-9]{1,10})?)|180(([.][0]{1,10})?))$/, 'g'),
    message: '请输入正确的经度',
  },
  // 邮箱
  email: {
    pattern: new RegExp(
      /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
      'g'),
    message: '邮箱格式不正确',
  },
  //人民币
  RMB: {
    pattern: new RegExp("^([\u4e00-\u9fa5]|[.])*$"),
    message: "不能含有中文"
  },
  // 企业税号
  taxNumber: {
    pattern: new RegExp(/^[A-Z0-9]{15}$|^[A-Z0-9]{17}$|^[A-Z0-9]{18}$|^[A-Z0-9]{20}$/),
    message: "税号格式不正确"
  },
  //邮政编码
  postalCode: {
    pattern: new RegExp(/^(0[1-7]|1[0-356]|2[0-7]|3[0-6]|4[0-7]|5[1-7]|6[1-7]|7[0-5]|8[013-6])\d{4}$/),
    message: "邮政编码不正确"
  },
  //统一社会信用代码
  creditCode: {
    pattern: new RegExp(/^(0[1-7]|1[0-356]|2[0-7]|3[0-6]|4[0-7]|5[1-7]|6[1-7]|7[0-5]|8[013-6])\d{4}$/),
    message: "邮政编码不正确"
  },
  // 车牌号 "京A00599"
  carNumber: {
    pattern: new RegExp(/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]$/),
    message: "车牌号不正确"
  },
  // 新能源车
  carNumberNewEnergy: {
    pattern: new RegExp(/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z](?:((\d{5}[A-HJK])|([A-HJK][A-HJ-NP-Z0-9][0-9]{4}))|[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳])$/),
    message: "新能源车,车牌号不正确"
  },
  // 护照
  passport: {
    pattern: new RegExp(/(^[EeKkGgDdSsPpHh]\d{8}$)|(^(([Ee][a-fA-F])|([DdSsPp][Ee])|([Kk][Jj])|([Mm][Aa])|(1[45]))\d{7}$)/),
    message: "新能源车,车牌号不正确"
  },
  // 错误消息
  errors:[],
  // 状态
  status:true,
  // 验证是否成功
  validator: function (rule, str) {
    let result = true;
    // 规则数组
    if(rule instanceof Array){
      for(let i =0 ;i<= rule.length -1;i++){
        let Exp = this[rule[i]];
        if(Exp){
          if(!Exp.pattern.test(str)){
            this.status =false;
            this.errors.push(Exp.message);
          }
        }else{
          this.status =false;
          this.errors.push("验证规则:" + rule[i] +"不存在");
        }
      }
    }
    // 单个规则
    if(typeof rule =='string'){
      let Exp = this[rule];
      if(Exp){
        if(!Exp.pattern.test(str)){
          this.status =false;
          this.errors.push(Exp.message);
        }
      }else{
        this.status =false;
        this.errors.push("验证规则:" + rule +"不存在");
      }
    }
    return result;
  }
}
Posted in js | Leave a comment

node.js 的爬虫puppeteer基本使用

const puppeteer = require("puppeteer");

function timeout() {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 3000);
  });
}

module.exports = async (url) => {
 //打开浏览器chrome 路由
  const browser = await puppeteer.launch({
    executablePath: "/Applications/Google Chrome.app/Contents/MacOS/Google\ Chrome",
    headless: true
  });
// 创建自页面
  const page = await browser.newPage();
// 打开一个网页
  await page.goto(url, {waitUtil: "networkidle2"});

  await timeout();
 // 在页面中执行js
  let results = await page.evaluate(() => {
    const tmp = [];
    
    return tmp;
  })
// 返货js执行结构
  return results;
// 关闭chrmoe
  await browser.close();
}
Posted in node.js | Leave a comment

expect登录mysql

#!/usr/bin/expect

# 登录mysql

set user "root"
set host "localhost"
set password "****"
set db "wp-"
set port "3306"
set timeout 3000
spawn mysql -h $host -P $port -u $user -p
expect {
  "*Enter password:*" {
    send "$password\r";
    expect {
      "*mysql>*" {
        send  "SHOW DATABASES;\r";
        expect {
          "*mysql>*" {
            send  "use $db;\r";
            expect {
              "*Database changed*" {
                send  "show tables;\r";
                interact
              }
              "*ERROR*" {
                send  "SHOW DATABASES;\r";
                interact
              }
            }
          }
        }
      }
    }
  }
}
Posted in Linux, shell | Leave a comment

自己写一个简陋版Vue

    // 构造app函数
    function App(config,$){
        this["$"]= $;
        for( var i in config ) {
             console.log(i);
            this[i]= config[i];
        }
        this["AppInit"]=function(){
               // 这里this指向app
                let  properties = this.data;
                for( var i in properties ) {
                    // +--------------------------------------------------------
                    // |错误的写法,原因匿名函数内部this执行windows
                    // +--------------------------------------------------------
                    // |(function(){
                    // |    this[ "get" + i ] = function() {
                    // |        return this.data.i;
                    // |    };
                    // |    this[ "set" + i ] = function(val) {
                    // |        this.change(i,val);
                    // |        this.data.i = val;
                    // |    };
                    // |})();
                    // |console.log(this);
                    // +--------------------------------------------------------
                    
                    // +--------------------------------------------------------
                    // |注册getter()和setter()方法
                    // +--------------------------------------------------------
                    this.registerGetter(i);
                    this.registerSetter(i);
                };
                //挂载mounted到this上
                if(this.mounted != undefined){
                    for( var fun in this.mounted ){
                        this[fun]= this.mounted[fun];
                    }
                    
                }
          };
        this["registerGetter"]=function (propertiesName){
           this[ "get" +propertiesName ] = function() {
                return this.data[propertiesName];
            };
        };
        this["registerSetter"]=function (propertiesName){
            this[ "set" + propertiesName ] = function(val) {
                this.change(propertiesName,val);
                this.data[propertiesName] = val;
            };
        };
        this['change']=function(name,newVale){
            // 如果监听这个属性则把两次值传给函数
            if(this.watch[name] != undefined){
                this.runWatch = this.watch[name].handler;
                this.runWatch(newVale,this["get"+name]());
             }
            // 更新计算属性
            // 。。。。
            // 更新页面内容
            // 。。。。
        };
         this['runWatch'] =function (){},
        this.AppInit();
        // 下面可以自定义生命周期函数
        if(this['onLoad'] !=undefined ){
            this['onLoad']();
        }
        if(this['run'] != undefined){
            this['run']();
        }
    };

用法

 const app = new App({
        data:{
            "Name":"asd",
            "Age":19,
        },
        watch:{
          Group:{
                deep:true,
                handler:function(newVale,oldValue){
                    
                }
            }
        },
        onLoad:function(){
            this.setAge(10);
        },
        mounted:{
            
        },
        run:function (){
            
        }, $
    });
    window.app = app;
Posted in js | Leave a comment

超级全面的php文件操作

一、判断文件和目录

<?php
file_exists(string $filename);    //判断文件或目录是否存在
is_file(string $filename);        //判断给定文件名是否为一个正常的文件
is_dir(string $filename);         //判断给定文件名是否是一个目录
is_readable(string $filename);   //判断给定文件名是否存在并且可读.
is_writable(string $filename);   //判断给定文件名是否存在并且可写.
is_executable(string $filename);  //判断给定文件名是否可执行.
is_link(string $filename);        //判断给定文件名是否存在并且是一个符号连接文件(软连接文件).
?>

二、文件属性

<?php
// 获取指定文件的信息.如果filename是符号连接,
//则统计被连接文件,而不是符号连接本身.
stat(string $filename);

//获取由文件指针handle(由fopen()创建)所打开文件的统计信息.
//和stat()函数相同,除了它是作用于已打开的文件指针而不是文件名.
fstat(resource $handle);

//获取指定的文件信息.如果filename是符号连接,
//则统计符号连接本身,而不是被连接文件,其他和stat()相同.
lstat(string $filename);

上面三个函数的返回数组中的键值:

<?php
/**
 * dev      设备名
 * ino      inode号码
 * mode     inode保护模式
 * nlink    被连接数目
 * uid      所有者的用户id
 * gid      所有者的组id
 * rdev     设备类型,如果是inode设备的话
 * size     文件大小的字节数
 * atime    上次访问时间(Unix 时间戳)
 * mtime    上次修改时间(Unix 时间戳)
 * ctime    上次改变时间(Unix 时间戳)
 * blksize  文件系统 IO 的块大小
 * blocks   所占据块的数目
 */
filesize(string $filename);       //取得普通文件大小
filectime(string $filename);      //获取文件的创建时间
filemtime(string $filename);      //获取文件的修改时间
fileatime(string $filename);      //取得文件的上次访问时间
fileinode(string $filename);      //返回文件的索引节点(inode)
filegroup(string $filename);      //取得文件所属组`ID`
posix_getgrgid(int $gid);         //将组id其解析为包含组名`,`密码`,`组id`,
                                  //`组成员`组成的数组.
fileowner(string $filename);      //取得文件所有者`ID`.
posix_getpwuid(int $uid);         //将用户`id`其解析为包含`用户名`,`密码`,
                                  //`用户id`,`组id`、`家目录`、使用的
                                  //shell组成的数组.
filetype(string $filename);       //返回文件的类型.可能的值有
                                  //`fifo`,`char`,`dir`,`block`,
                                  //`link`,`file`,`unknown`,`.
fileperms(string $filename);      //取得文件的权限,返回十进制的数字,
                                  //要转换为八进制并取后4位.
substr(sprintf('%o', fileperms(string $filename)), -4);
//清除文件状态缓存,受影响的函数包括
// stat(), lstat(), file_exists(), is_writable(), is_readable(),
// is_executable(), is_file(), is_dir(), is_link(), filectime(),
// fileatime(), filemtime(), fileinode(), filegroup(),
// fileowner(), filesize(), filetype() 和 fileperms()
clearstatcache();
# 当使用任何列在受影响函数表中的函数时,PHP将缓存这些函数的返回信息以提供更快的性能.
# 如果在一个脚本中多次检查同一个文件,而该文件在此脚本执行期间有可能被删除或修改,
# 要清除文件状态缓存.必须注意的是,对于不存在的文件,PHP 并不会缓存其信息.如调用 
# file_exists()来检查不存在的文件
<?php
//将文件所属的组改成`groupv通过组名或组`ID`指定).
chgrp(string $filename,mixed $group);
//将文件的所有者改成用户user(由用户名或用户`ID`指定).
//只有超级用户可以改变文件的所有者.
chown(string $filename ,mixed $user);
//尝试设定文件的访问时间($time)和修改时间($atime).如果文件不存在,则会被创建.
touch (string $filename[,int $time=time()[,int $atime=time()]]);
//取得当前工作目录
getcwd();
//将PHP的当前目录改为`directory`.
chdir(string $directory);
//尝试将`filename`所指定文件的权限改成mode所给定的.`chmod("/dir/file", 0755)`;
chmod(string $filename,int $mode);
//获取当前脚本的索引节点(inode)
getmyinode()
//获取当前 PHP 脚本拥有者的用户组`ID`.
getmygid()
//获取 PHP 脚本所有者的`UID`
getmyuid()
//获取 PHP 进程的`ID`
getmypid()
//获取当前`PHP`脚本所有者名称
get_current_user()
//获取页面最后修改的时间
getlastmod()
//返回符号连接的内容.
readlink(string $path)
//对于已有的`target`建立一个名为`link`的符号连接.
symlink(string $target,string $link)
//获取一个连接的信息.本函数用来验证一个连接(由`path`所指向的)是否确实存在
linkinfo(string $path)
//函数返回指定的目录所在磁盘分区的可用空间
disk_free_space()
//函数返回指定的目录所在磁盘分区的总容量
disk_total_space();
Posted in php | Leave a comment

Linux 使用expect交互方式ssh登录

#!/usr/bin/expect

# Ubuntu 18.04使用expect登录
set user "用户名"
set host "ip"
set password "密码"
set timeout 3000
spawn ssh $user@$host
expect  {
  "*yes/no*" {send "yes\r";exp_continue}
  "*password*" {
    send "$password\r";
    expect {
      "*please try again*" {
        puts "密码错误";
        exit
      }
      "*${user}@*" {
        # 你要执行的操作
        send "sudo apt-get update\r"
        # 将控制返回给终端
        interact
      }
    }
  }
}
Posted in Linux | Leave a comment

Linux 中添加登录通知脚本

#!/bin/bash

# 把下面代码复制到etc/profile文件中即可
server=$(hostname)
#获取登录者的用户名
#user=$USER
user=$(getent passwd `who` | head -n 1 | cut -d : -f 1)
#echo $user
if [ "" = "$user" ]; then
user="default"
fi
#获取登录者的IP地址
ip=${SSH_CLIENT%% *}
#echo $ip
if [ "$ip" = "" ]; then
ip="default"
fi

url="https://www.shiguangxiaotou.com/wp-json/crud/api/server/login"
curl -X POST --data-urlencode "server=$server" --data-urlencode "name=$user" --data-urlencode "ip=$ip" $url
Posted in Linux | Leave a comment

一个简单的php socket服务端

<?php

/**
 * 一个简单的socke服务端
 */
class Socket{
    public $address ="0.0.0.0";
    public $port=8081;
    private $_server;

    public function __construct(){
        echo "开始创建对象...".PHP_EOL;
        $socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP) or self::error($socket );
        echo "绑定端口:".$this->address.":".$this->port."...".PHP_EOL;
        $tmp = socket_bind($socket,$this->address,$this->port) or self::error($tmp);;
        echo "开始监听...".PHP_EOL;
        $tmp = socket_listen($socket, 4) or self::error($tmp );
        echo "服务启动成功".PHP_EOL;
        $this->_server = &$socket;
    }

    public static function error($server){
        die(socket_strerror(socket_last_error($server)) . "/n");
    }

    /**
     * 解析http报文为数组
     * @param $data
     * @return array
     */
    public function analysisBuffer($data){
        $herder =[];
        $lines = preg_split("/\r\n/",$data);
        foreach ($lines as $line){
            $row =explode(": ",$line);
            if(count($row) ==2){
                $herder[$row[0]] =$row[1];
            }
        }
        return $herder;
    }

    /**
     * 返回报文
     * @param $buffer
     * @param $client
     * @return bool
     */
    public function hand_shake($buffer,$client){
        $headers = $this->analysisBuffer($buffer);
        $key =$headers['Sec-WebSocket-Key'];
        $new_key = base64_encode(sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));
        $message = "HTTP/1.1 101 Switching Protocols\r\n";
        $message .= "Upgrade: websocket\r\n";
        $message .= "Sec-WebSocket-Version: 13\r\n";
        $message .= "Connection: Upgrade\r\n";
        $message .= "Sec-WebSocket-Accept: " . $new_key . "\r\n\r\n";
        socket_write($client,$message,strlen($message));
        return true;
    }

    /**
     * 加密
     * @param $message
     * @return string
     */
    public function encode($message){
        $len = strlen($message);
        if($len <=125){
            return "\x81".chr($len).$message;
        }elseif ($len<=65535){
            return "\x81".chr(126).pack("n",$len).$message;
        }else{
            return "\x81".chr(127).pack("xxxxN",$len).$message;
        }
    }

    /**
     * 解密
     * @param $buffer
     * @return string|null
     */
    public function decode($buffer){
        $len = $masks = $data = $decode =null;
        $len = ord($buffer[1]) & 127;
        if($len === 126){
            $masks = substr($buffer,4,4);
            $data = substr($buffer,8);
        }elseif ($len ===127){
            $masks = substr($buffer,10,4);
            $data = substr($buffer,14);
        }else{
            $masks = substr($buffer,2,4);
            $data = substr($buffer,6);
        }
        for ($index =0;$index <strlen($data);$index++){
            $decode .= $data[$index] ^ $masks[$index % 4];
        }
        return $decode;
    }

    public function run(){
        $clients = [$this->_server];
        do {
            $read =$clients;
            $write =null;
            $except =null;
            if (socket_select($read,$write,$except,null)>0){
                foreach ($read as $item){
                    if($item === $this->_server){
                        // 首次链接
                        if(!$socket_client = socket_accept($item)){
                            continue;
                        }else{
                            $client_data = @socket_read($socket_client,1024);
                            if($client_data=== false){
                                socket_close($socket_client);
                            }
                            // 建立握手
                            $this->hand_shake($client_data ,$socket_client);
                            // 获取客户端信息
                            socket_getpeername($socket_client,$ip,$port);
                            $clients[$ip.":".$port]=  $socket_client;
                            echo "有一个新的链接".$ip.":".$port."\n";
                        }
                    }else{
                        $result = @socket_recv($item,$msg,1024,0);

                        if($result === false){continue;}
                        if ($result ===0 ){
                            socket_close($item);
                            $key1 =array_search($item,$read);
                            unset($read[$key1]);
                            $key2 = array_search($item,$clients);
                            unset($clients[$key2]);
                        }else{
                            // 解码客户端消息
                            $web_msg= $this->decode($msg);
                            $id = array_search($item ,$clients);
                            echo "client:".$id ."说:".$web_msg."\n";
                            // 加密客户端消息
                            $response = $this->encode($web_msg);
                            // 广播
                            foreach ($clients as $client){
                                if($client != $this->_server ){
                                    if(false == @socket_write($client,$response,strlen($response))){
                                        socket_close($client);
                                        $key1 = array_search($client,$read);
                                        unset($read[$key1]);
                                        $key2 = array_search($client,$clients);
                                        unset($clients[$key2]);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } while (true);
    }
}

$server = new Socket();
$server->run();
Posted in php, socket | Leave a comment

php 拓展包,依赖包,可视化

php 解析composer依赖关系,生成视图

php 解析composer依赖关系,生成视图
use crud\models\Rely;
$model = new Rely();
$model->vendorDir = '/vendor');
//$model->env =false;
$model->baseComposerJson = "/composer.json";
$model->baseComposerLock = "/composer.lock";
echo $model-> renderHtml();
<?php


namespace crud\models;


use yii\base\Model;

/**
 * 生成composer 依赖关系图
 * @package crud\models
 */
class Rely extends Model
{

    public $vendorDir = '';
    public $baseComposerJson = '';
    public $baseComposerLock='';
    public $env = true;
    public $_require=[];
    public $projectName="shiguangxiaotou/wordpress";
    public $data =[
        "nodes" => [
//            [
//                "id" => "0",
//                "name" => "shiguangxiaotou/wordpress",
//                "symbolSize" => 20,
//                "value" => "1.3.0",
//                "category" => 0
//            ],
        ],
        "links" => [
//            "source" => $nodeId,
//            "target" => $fatherId
        ],
        "categories" => [
//            ['name'=>'adads']
        ]
    ];

    /**
     * 获取已安装拓展包已安装版本
     * @param $projectName
     * @return mixed|string
     */
    public function getVersion($projectName){
        $str_json = file_get_contents($this->baseComposerLock);
        $arr = json_decode($str_json,true);
        $packages = ($this->env) ? $arr['packages']:$arr['packages-dev'];
        $results ='';
        foreach ( $packages as $package){
            if($package['name']==$projectName){
                return $package['version'];
            }
        }
        return  $results;
    }

    /**
     * 获取composer.json的依赖包名称
     * @param $file
     * @param bool $env
     * @return array
     */
    public static function getRequire($file,$env=true){
        $requires = $names=[];
        if(file_exists($file)){
            $json = file_get_contents($file);
            $arr =json_decode($json,true);
            if($env){
                $requires = !empty($arr['require'])? $arr['require']:[];
            }else{
                $requires1 = !empty($arr['require'])? $arr['require']:[];
                $requires2 = !empty($arr['require-dev'])? $arr['require-dev']:[];
                $requires = array_merge($requires1,$requires2);
//                $requires = !empty($arr['require-dev'])? $arr['require-dev']:[];
//                logObject($requires2);
            }
            $names = array_keys($requires);
        }
        return $names;
    }

    /**
     * 递归获取所以第三方插件
     * @param array $data
     * @param $projectName
     */
    public  function getRely($projectName,&$data=[]){
        $tmp = self::getRequire($this->vendorDir.'/'.$projectName."/composer.json");
        if(!empty($tmp)) {
            foreach ($tmp as $value) {
                $data[$projectName][$value]=[] ;
                $tmp2 =self::getRequire($this->vendorDir.'/'.$value."/composer.json");
                if(!empty($tmp2)){
                    self::getRely($value,$data[$projectName][$value]);
                }

            }
        }
    }

    /**
     * 判断节点是否存在
     * @param $projectName
     * @return bool
     */
    public function isset_node($projectName){
        foreach ($this->data['nodes'] as $node){
            if($node['name'] == $projectName){
                return true;
            }
        }
        return  false;
    }

    /**
     * 获取节点id
     * @param $nodeName
     * @return mixed
     */
    public  function getNodeId($nodeName){
        foreach ($this->data['nodes'] as $node){
            if($node['name'] == $nodeName){
                return $node['id'];
            }
        }
    }

    /**
     * 递归创建Echarts数据结构
     * @param $fatherId
     * @param $categoryId
     * @param $nodeName
     * @param $nodes
     * @param $data
     */
    public  function  recursionNodes($fatherId,$categoryId,$nodeName,$nodes,&$data){
        if(!$this->isset_node($nodeName)){
            $nodeId =count($data['nodes']);
            if($nodeId ==0){
                $data['nodes'][]=[
                    "id" => $nodeId,
                    "name" => $nodeName,
                    "symbolSize" => 20,
                    "value" => $this->getVersion($nodeName),
                    "category" => $categoryId
                ];
            }else{
                $data['nodes'][]=[
                    "id" => $nodeId,
                    "name" => $nodeName,
                    "value" => $this->getVersion($nodeName),
                    "category" => $categoryId
                ];
            }

            if($nodeId !==$fatherId){
                $data['links'][]=[
                    "source" => $nodeId,
                    "target" => $fatherId
                ];
            }
        }else{
            $nodeId = $this->getNodeId($nodeName);
            // 要现实复杂依赖关系,请取消注释
//            if($nodeId !==$fatherId){
//                $data['links'][]=[
//                    "source" => $nodeId,
//                    "target" => $fatherId
//                ];
//            }
        }



        if (!empty($nodes)){
            $categoryId = count( $this->data["categories"]);
            $this->data["categories"][]=["name"=>$nodeName];
            foreach ($nodes as $name=>$v){
                $this->recursionNodes($nodeId,$categoryId,$name,$v,$data);
            }
        }

    }


    /**
     * 解析依赖,并创建eCharts数据结构
     * @return array
     */
    public function getRequireAll(){
        // 获取所有加载的拓展
        $base = self::getRequire($this->baseComposerJson,$this->env);
        $this->_require[$this->projectName]=[];
        foreach ($base as $value){
            $this->_require[$this->projectName][$value]=[];
            $this->getRely($value, $this->_require[$this->projectName][$value]);
        }
        $results = $this->_require;
        $nodeId = $categoriesId = 0;
        foreach ($results as $key =>$value){
            $this->recursionNodes($nodeId,$categoriesId,$key,$value,$this->data);
            $categoriesId++;
        }
       return  $this->data;
    }

    /**
     * 直接生成html文件
     * @return string
     */
    public function renderHtml(){
        $json_str = json_encode( $this->getRequireAll(),true);
        return <<<HTML
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
</head>
<body>
    <div id="container" style="width: 100%;height: 800px"></div>
</body>
<script type="text/javascript" src="https://fastly.jsdelivr.net/npm/jquery"></script>
<script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script>
<script>
    var dom = document.getElementById('container');
    var myChart = echarts.init(dom, null, {
        renderer: 'canvas',useDirtyRect: false
    });
    var graph = {$json_str}
    var option= {
      tooltip: {},
      legend: [
        {
          data: graph.categories.map(function (a) {
            return a.name;
          })
        }
      ],
      series: [
        {
          name: 'shiguangxiaotou/crud',
          type: 'graph',
          layout: 'force',
          data: graph.nodes,
          links: graph.links,
          categories: graph.categories,
          roam: true,
          label: {
            show: true,
            position: 'right',
            formatter: '{b}'
          },
          labelLayout: {
            hideOverlap: true
          },
          scaleLimit: {
            min: 2,
            max: 10
          },
          lineStyle: {
            color: 'source',
            curveness: 0.3
          }
        }
      ]
    };
    myChart.showLoading();
    myChart.hideLoading();
    myChart.setOption(option);
    if (option && typeof option === 'object') {
      myChart.setOption(option);
    }
    window.addEventListener('resize', myChart.resize);
</script>
</html>
HTML;
    }

}
Posted in php | Tagged | Leave a comment

php 获取函数或方法的形参和实参

// 定义一个函数
funcrion my_fun($a,$b,$c,$d,$e,$n){
  my_fun2($args);
}
// 有时有需要将函数my_fun的多个参数合并传入另一个函数时,
// 特别麻烦需要一个手写合并为一个数组,当参数太多时,特别麻烦

解决方法一:func_num_args() 将参数合并

funcrion my_fun($a,$b,$c,$d,$e,$n){
  my_fun2(func_get_args());
}
var_dump(my_fun("asd1","asd2","asd3","asd4","asd5","asd6"));

输出

[
"asd1","asd2","asd3","asd4","asd5","asd6"
]

缺点

func_get_args 返回的是一个数字索引数组,如何返回key=>value 的关联数组呢

解决方法二:new ReflectionFunction 将参数合并

funcrion my_fun($a,$b,$c,$d,$e,$n){
  my_fun2(getFunctionArgs(__FUNCTION__));
}
/**
 * 获取函数的的形参名称
 * @param $functionName
 * @return false|array
 */
function getFunctionArgs($functionName){
    if (function_exists($functionName)) {
        try {
            $fun = new  ReflectionFunction($functionName);
        } catch (ReflectionException $e) {
            return false;
        }
        $paramsName = [];
        foreach ($fun->getParameters() as $parameter) {
            $paramsName[] = $parameter->name;
        }
        return $paramsName;
    }
}
var_dump(my_fun("asd1","asd2","asd3","asd4","asd5","asd6"));

输出

[
  "a"=>"asd1","b"=>"asd2",
  "c"=>"asd3","d"=>"asd4",
  "e"=>"asd5","n"=>"asd6"
]

缺点

ReflectionFunction 虽然返回了关联数组但是,只能用于函数,对象的方法不行

解决方法三:ReflectionMethod 对象方法的形参实参合并

funcrion my_fun($a,$b,$c,$d,$e,$n){
  my_fun2(getParams());
}
/**
 * 获取函数的的形参名称
 * @param $functionName
 * @return false|array
 */
function getFunctionArgs($functionName){
    if (function_exists($functionName)) {
        try {
            $fun = new  ReflectionFunction($functionName);
        } catch (ReflectionException $e) {
            return false;
        }
        $paramsName = [];
        foreach ($fun->getParameters() as $parameter) {
            $paramsName[] = $parameter->name;
        }
        return $paramsName;
    }
}

/**
 * 获取一个类的某个方法的形参名称
 * @param $className
 * @param $methodName
 * @return false|array
 */
function getMethodArgs($className, $methodName){
    try {
        $ref = new ReflectionMethod($className, $methodName);
    } catch (ReflectionException $e) {
        return false;
    }
    $paramsName = [];
    foreach ($ref->getParameters() as $param) {
        $paramsName[] = $param->name;
    }
    return $paramsName;
}

/**
 * 兼容对象和函数的写法
 * @return array|mixed
 */
function getParams(){
    $backtrace = debug_backtrace()[1];
    $functionName = $backtrace['function'];
    if (isset($backtrace["class"])) {
        $paramsNames = getMethodArgs($backtrace["class"], $functionName);
    } else {
        $paramsNames = getFunctionArgs($functionName);
    }
    return ($paramsNames and !empty($paramsNames))
        ? array_combine($paramsNames, $backtrace["args"])
        : $backtrace["args"];
}

var_dump(my_fun("asd1","asd2","asd3","asd4","asd5","asd6"));

输出

[
  "a"=>"asd1","b"=>"asd2",
  "c"=>"asd3","d"=>"asd4",
  "e"=>"asd5","n"=>"asd6"
]

最终

getParams() 函数通过兼容写法ReflectionMethod 类和 ReflectionFunction类,实现快速合并形参实参

Posted in php | Leave a comment

jvectorMap 地理数据包整理集合

jvectormap 地图数据整理 一些年久失修的好东西

jVectorMap 是一个基于矢量、跨浏览器和跨平台的组件,用于在 Web 上进行与地理相关的交互式数据可视化。它提供了许多功能,如平滑缩放和平移、完全可定制的样式、标记、标签和工具提示。

您可以在 官方网站上找到地图、文档、示例等。示例子位于 ??

安装

$ npm install jvectormap-maps-data
$ git clone git@github.com:shiguangxiaotou3/jvectormap-maps-data.git
$ composer require shiguangxiaotou/jvectormap-maps-data

使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="./../dist/css/jquery-jvectormap.css">
</head>
<body>
     <div id="world-map" style="height: 500px; width: 100%;"></div>
</body>
<!-- jvectormap -->
<script src="./../node_modules/jquery/dist/jquery.js"></script>
<script src="./js/jquery-jvectormap-1.2.2.min.js"></script>
<script src="./js/jquery-mousewheel.js"></script>
<script>
    jQuery(function ($) {
        let visitorsData = {
            US: 398, GB: 320, RU: 3000,
            SA: 400, CA: 1000, IN: 800
        };
        $('#world').vectorMap({
            map: 'world-merc',
            backgroundColor: 'transparent',
            regionStyle: {
                initial: {
                    fill: '#e4e4e4',
                    'fill-opacity': 1,
                    stroke: 'none',
                    'stroke-width': 0,
                    'stroke-opacity': 1
                }
            },
            series: {
                regions: [
                    {
                        values: visitorsData,
                        scale: ['#ebf4f9', '#92c1dc'],
                        normalizeFunction: 'polynomial'
                    }
                ]
            },
            onRegionLabelShow: function (e, el, code) {
                if (typeof visitorsData[code] != 'undefined')
                    el.html(el.html() + ': ' + visitorsData[code] + ' new visitors');
            }
        });
</script>
</html>
Posted in package | Leave a comment

GitHub Desktop for Mac 汉化语言包

适用范围

  • MacBook Air macOS Monterey 12.6 (m1)
  • GitHub DeskTop for Mac 3.1.1 (arm64)
# 下载
npm install github-desktop-for-mac-language-zh-cn
# 安装 
# cd you project root path run:
sudo bash install.sh 
# or
sudo bash install.sh install
# 还原
sudo bash install.sh uninstall
github desktop 汉化包
Posted in package | Leave a comment

Vue-CLI中配置postcss-pxtorem自动将px转换为rem

1.安装postcss-pxtorem

$ npm install postcss postcss-pxtorem --save-dev

2.添加配置项package.json

{
  "name": "myweb",
  "version": "0.1.0",
  "private": true,
  //...
  "postcss": {
    "plugins": {
      "autoprefixer": {},
      "postcss-pxtorem": {
        "rootValue": 37.5,
        "propList": [
          "*"
        ]
      }
    }
  },
 //...
}

3.创建src/utils/rem.js

window.onresize = function () {
    getSize();
};
function getSize  () {
    var deviceSize = document.documentElement.clientWidth;
    console.log("设备宽度:", deviceSize);
    var fontSize = (deviceSize / 20);  
    // 这里的 20 * rootValue = 你的设计稿宽度px
    // 例如我的设计稿宽750px : 20 *  rootValue(37.5) = 750px
    console.log("字体大小:",fontSize +"px");
    document.documentElement.style.fontSize = fontSize +"px";
}
getSize(); // 这里必须在页面打开时先执行一次

4.main.js 导入rem.js

import "./utils/rem.js"

5.总结

postcss-pxtorem只是一个方便开发的插件,你可以在源码中直接写设计稿单位xp。在调试、开发打包时自动转换为rem。在Vue-Cli中项目中默认自带安装了Postcss,只需要配置和动态修改DOM根元素fontSize。Vue-Cli会帮你自动完成.

Posted in js, Vue | Leave a comment

js中new Date().format()方法不可用问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
</html>

<script type="javascript">
    Date.prototype.format = function(format){
        if((format = "" || format == undefined)){
            format ="yyyy-mm-dd h:m:s"
        }
        let conf =['yyyy','mm', 'dd','h','m','s','S'];
        let arr = {
            'yyyy':this.getFullYear(),
            'mm':this.getMonth() +1,
            'dd':this.getDate(),
            'h':this.getHours(),
            'm':this.getMinutes(),
            's':this.getSeconds(),
            'S':this.getMilliseconds(),
        };
        conf.forEach(function(item){
            format= format.replace(item,arr[item])
        });
        return format;
    };
    // 添加到Vue原型上
    Vue.prototype.$date = function (value) {
        return new Date();
    };
    // 使用
    new Vue({
        el: '#app',
        data:function(){
            return {
                time:46545
            }
        }
        computed:{
            time_str(){
                return   this.$date(this.time).format();
            }
        }
    });
</script>
Posted in js, Vue | Leave a comment

2022年前端CSS 框架排名

### Bootstarp
- 简单 强悍 响应式布局 移动端优先
- https://getbootstarp.com
- Star: 15.9w
### Ant Design
- 企业级应用UI 高质量的React组件(蚂蚁金服)
- https://ant.design/index-cn
- Star: 8.14w
### Material-UI
- React 组件
- https://material-ui.com/zh/
- Star:8.04w
### Tailwind CSS
- 低级别的CSS框架 简化构建 自定义组件
- https://tailwindcss.com
- Star: 5.96w
### Element
- 饿了么
- https://element.eleme.cn/#/zh_CN
- Star: 5.25w
### Materialize
- 响应式
- https://materializecss.com
- Star: 3.87w
### WeUI
- 微信
- https://weui.io
- Star: 2.65w
### Layui
 - 经典模块化前端框架 弹出层非常友好
 - https://wwwlayui.com
 - Star: 2.64w
### iView
- 基与vue.js组件库
- https://iview.talkingdata.com
- Star: 2.4w
### Gentelella Admin
- 基与Bootstarp 4
- https://colorlib.com/polygon/gentelella/index.html
- Star: 2.06w
### Vant
- 移动端组件库
- https://vant-contrib.gitee.io/vant/#/zh-CN
- Star: 2.0w
### NES.CSS
- 模仿 掌机的css库
- https://nostalgic-css.github.io/NES.css/#
- Star: 1.88w
### Vant
- 移动端组件库
- https://vant-contrib.gitee.io/vant/#/zh-CN
- Star: 2.0w
### Cube UI
- 滴滴
- https://didi.github.io/cube-ui/
- Star: 9k
 
Posted in css | Leave a comment

wordpress 站点统计jMaps插件(测试版)

jMaps是一个用于统计站点访问量的插件,通过ipinfo显示访问者的物理地址。

主要功能:

  • 记录访问者ip
  • 通过ip解析访问者的物理地址
  • 内置ace代码编辑器
  • 内建mac风格代码显示
  • 修复中国地区头像无法加载问题
  • 通过wordpress内置stmp实现,邮件的STMP服务

目前是测试版,如何出现问题请留言….

附件:点击下载

Posted in wordpress | Leave a comment