彩虹海是我哒 https://blog.flxxyz.com/ zh-CN 人间不值得 Thu, 13 Jun 2019 14:45:00 +0800 Thu, 13 Jun 2019 14:45:00 +0800 一觉醒来已是2076 https://blog.flxxyz.com/chat/2019/cyberpunk-2077.html https://blog.flxxyz.com/chat/2019/cyberpunk-2077.html Thu, 13 Jun 2019 14:45:00 +0800 冯小贤 cyberpunk-2077.jpg

GOG启动,预购!

]]>
2 https://blog.flxxyz.com/chat/2019/cyberpunk-2077.html#comments https://blog.flxxyz.com/feed/chat/2019/cyberpunk-2077.html
第二代站点更新计划 https://blog.flxxyz.com/chat/2019/second-generation-site-update-plan.html https://blog.flxxyz.com/chat/2019/second-generation-site-update-plan.html Tue, 11 Jun 2019 20:47:00 +0800 冯小贤 最近感觉好卡啊

tx香港像炸了?既然备案了还是考虑再搬进国内8

之前用过面板,纯手搭,现在还是用的宝塔老版本,计划备份站点,重置服务器,几天前在屋里虚拟化设备上用docker配置过实例,php+nginx的站点可以统一使用这套实例的配置alpine-nginx-php7

]]>
3 https://blog.flxxyz.com/chat/2019/second-generation-site-update-plan.html#comments https://blog.flxxyz.com/feed/chat/2019/second-generation-site-update-plan.html
裸辞一个月 https://blog.flxxyz.com/chat/2019/naked-for-a-month.html https://blog.flxxyz.com/chat/2019/naked-for-a-month.html Mon, 03 Jun 2019 19:56:00 +0800 冯小贤 看了下上一篇文章发布时间还是在两个月之前,哇,一下在家玩了一个多月了,不在公司写辣鸡代码时间过得真快 (逃

想下在家都干嘛了,睡觉,玩游戏,看电影,写代码,看书,参加活动,拼模型,捡垃圾,适当的运动,房间整理。

大致的时间分配如下图
QQ截图20190603202936.png

看小米手环每天睡觉的时间差不多都在10个小时,steam收藏家的游戏买了还要玩?当然是玩手游啦,荒野乱斗简单快速的玩法真的不错,固定的四张地图场景,还有一张活动地图,固定的地图玩法可以,在时间段内推出新活动,新活动会对场景物体进行微调,增加一些特定玩法,队伍的奖励机制也很巧妙,除非你是倒数123,都会有奖励,每场比赛类似于排位赛,胜利会获得奖杯(英雄个人奖杯与总奖杯),总奖杯只会一直累加,失败只会减少英雄个人奖杯,玩长时间真的有毒。

写代码就是把以前写的东西优化,新想法实现出来,其实就是在摸鱼。

书的确在看,前段时间还去参加了又拍云组织的openresty技术分享会,拿到了纪念衫还有一本《自己动手实现lua》,粗略的看了下是使用golang实现lua虚拟机,语法树,编译器,暂时放下看算法中,但是看到去年开年买的到现在还没开封😓,发现去年一年好像都没什么时间能看看书,时间管理不合格啊。

其他花时间最多的应该就是看电影了,看到了在妇联期间好电影的票房惨淡,沙雕剧情的大卖,不由得想起冯导说的,

有那么多的垃圾电影,因为有很多垃圾观众

另外四五月份的艺术片真的还蛮好看的(内心OS的呐喊),这几天整个观影清单出来,这段时间的就放文章下面吧。

突然还入了捡垃圾薅羊毛的坑,现在是冷静下来了。

适当运动其实就是50个俯卧撑,50个深蹲,20个仰卧起坐(肥宅无力,这几天天气开始不下雨入夏可以考虑出去晨跑夜跑了。

定做了两个置物架,把以前零散放着的服务器,书籍,手办,摆在了一起。
QQ图片20190603214043.jpg

电影清单

]]>
6 https://blog.flxxyz.com/chat/2019/naked-for-a-month.html#comments https://blog.flxxyz.com/feed/chat/2019/naked-for-a-month.html
Vue 实现基本手机号登录界面 https://blog.flxxyz.com/technology/2019/vue-login-interface-base.html https://blog.flxxyz.com/technology/2019/vue-login-interface-base.html Tue, 16 Apr 2019 17:12:00 +0800 冯小贤 把最近整的一些小玩意整理分享一下

手机号登录,分析一下页面可以知道一般是有两个按钮(获取验证码,登录)两个框(输入手机号,输入验证码)

所以有了下面这个玩意(不看具体功能,只看结构)

<template>
    <div class="login-wrapper">
        <div class="title-bar">登录</div>
        <div class="wrapper phone-wrapper">
            <span class="title">手机号</span>
            <input class="input phone" type="text" placeholder="手机号">
        </div>
        <div class="wrapper code-wrapper">
            <span class="title">验证码</span>
            <input class="input code" type="number" placeholder="验证码">
            <div class="send">获取验证码</div>
        </div>
        <div class="wrapper btn-wrapper">
            <div class="input btn">登录</div>
        </div>
    </div>
</template>

这个时候就可以开始写逻辑了,也是来简单分析一下,登录需要点击,获取验证码需要点击并且能倒数秒数,也就是动态修改文字,体验好一点可以检查限定手机号位数,验证码位数。

那就差不多是下面这个样子

<template>
    <div class="login-wrapper">
        <div class="title-bar">登录</div>
        <div class="wrapper phone-wrapper">
            <span class="title">手机号</span>
            <input class="input phone" type="text" placeholder="手机号"
                   :value="phone"
                   ref="phone" v-on:change="changePhone" v-on:input="changePhone">
        </div>
        <div class="wrapper code-wrapper">
            <span class="title">验证码</span>
            <input class="input code" type="number" placeholder="验证码"
                   :value="code"
                   ref="code" v-on:change="changeCode" v-on:input="changeCode">
            <div @click="loginCode" class="send">{{codeText}}</div>
        </div>
        <div class="wrapper btn-wrapper">
            <div class="input btn" @click="login">登录</div>
        </div>
    </div>
</template>

<script>
        name: "LoginPhone",
        data() {
            return {
                phone: '',  //输入框中的手机号
                code: '',  //输入框中的验证码
                codeText: '获取验证码',  //倒计时显示文字
                timingBoard: 60,  //倒计时数
                timer: null,  //一个定时器,用来倒数验证码
            }
        },
        methods: {
            loginCode() {},   //获取验证码
            login() {},       //登录
            changePhone() {}, //检查手机号长度
            changeCode() {},  //检查验证码长度
        }
</script>

有了这些已经足够你实现出一个基本的手机号登录界面了,如需完全代码请点击下面gist链接

完整代码参阅: https://gist.github.com/flxxyz/64ceb06a0754d67a771b3e3e7dc94d48

]]>
4 https://blog.flxxyz.com/technology/2019/vue-login-interface-base.html#comments https://blog.flxxyz.com/feed/technology/2019/vue-login-interface-base.html
Vue 注册全局指令解析markdown https://blog.flxxyz.com/technology/2019/vue-global-register-directive.html https://blog.flxxyz.com/technology/2019/vue-global-register-directive.html Tue, 26 Mar 2019 15:03:00 +0800 冯小贤 说实话用了这么长时间的vue,都没看过API,这几天重构博客偶然发现Vue.directive,挺厉害的样子

总是看到这里用Vue.use(ElementUi),那里用Vue.use(axios),一直停留在了用的层面,正好我发现编写markdown解析实例的消耗好像有点大,直接处理成指令或许会方便很多(真的方便了很多,少写了一堆方法)

简单描述一下流程吧

渲染文章的组件在挂载的生命周期中,会查询本地记录中是否存在对应的文章,不存在就发起请求线上查找,否则404。
文章为markdown内容,考虑让前端处理直接解析出来(毕竟前端性能过剩233),减少后端逻辑处理负担,一致性什么现在是不需要考虑的。
markdown解析器就用marked,完成逻辑如下

//main.js

import Vue from 'vue'
import App from './App'
import markdown from './markdown';

//注入markdown解析器
Vue.use(markdown.install)
Vue.prototype.$marked = markdown.marked

new Vue({
    store,
    router,
    render: h => h(App)
}).$mount('#app')

集成marked制成插件形式暴露

//markdown.js

import marked from 'marked'
import('highlight.js/styles/atom-one-dark.css')

marked.setOptions({
    renderer: new marked.Renderer(),
    pedantic: false,
    gfm: true,
    tables: true,
    breaks: false,
    sanitize: false,
    smartLists: true,
    smartypants: false,
    xhtml: false,
    highlight(code) {
        return require('highlight.js').highlightAuto(code).value;
    },
})

let install = (Vue) => {
    if (install.installed) return;
    Vue.directive('markdown', {
        bind: (el, binding, vnode) => {
            el.innerHTML = marked(binding.value)
        },
        update: (el, binding, vnode) => {
            el.innerHTML = marked(binding.value)
        }
    })
}

export default {
    marked,
    install,
}

在标签上使用v-markdown指令

//Test.vue

<template>
    <div>
        <div v-if="isNotFound">404</div>
        <div v-else v-markdown="article"></div>
    </div>
</template>

<script>
    const 这是一个查找文章的接口 = function () {
        return new Promise((resolve, reject) => {resolve(id)})
    }

    export default {
        name: "Test",
        data() {
            return {
                article: '',
                isNotFound: true,
            }
        },
        methods: {
            handlerArticle(id) {
                //查找本地文章
                let a = this.findArticle(id, async (id) => {
                    return await 这是一个查找文章的接口(id);
                })
                if (a == null) {
                    return 404;
                }

                return a;
            },
            findArticle(id, callback) {
                // let res = '## Test';
                let res = null;
                if (res === null) {
                    return callback(id);
                }

                return res;
            }
        },
        mounted() {
            //用id来查找文章
            let a = this.handlerArticle(123);

            if (a === 404) {
                //跳到错误页面
            }

            //处理loading
            this.isNotFound = false;
            this.article = a;  //将markdown内容直接保存到变量
        }
    }
</script>

完整代码参阅: https://gist.github.com/flxxyz/93e009d32ecd7e0c6785a52571577cd7

]]>
0 https://blog.flxxyz.com/technology/2019/vue-global-register-directive.html#comments https://blog.flxxyz.com/feed/technology/2019/vue-global-register-directive.html
预定samsung s10,真香 https://blog.flxxyz.com/chat/2019/samsung-s10.html https://blog.flxxyz.com/chat/2019/samsung-s10.html Fri, 08 Mar 2019 15:54:00 +0800 冯小贤 u11同学你可以休息一下了

]]>
1 https://blog.flxxyz.com/chat/2019/samsung-s10.html#comments https://blog.flxxyz.com/feed/chat/2019/samsung-s10.html
firewall骑墙操作 https://blog.flxxyz.com/technology/2019/firewall-forward-ssr.html https://blog.flxxyz.com/technology/2019/firewall-forward-ssr.html Fri, 22 Feb 2019 11:06:00 +0800 冯小贤 蹭了学生优惠,买了个阿里云轻服务器,5M带宽转国外线路减少丢包概率还不错,ns联机美滋滋,不过据说港服联机服务要出了,不知道联机质量会怎么样

firewall中继栗子

# 打开ip伪装
firewall-cmd --add-masquerade --permanent

# 添加端口协议
firewall-cmd --add-forward-port=port=中转后的端口:proto=tcp:toport=酸酸乳端口:toaddr=酸酸乳地址 --permanent
firewall-cmd --add-forward-port=port=中转后的端口:proto=udp:toport=酸酸乳端口:toaddr=酸酸乳地址 --permanent

# 重载一下
firewall-cmd --reload
]]>
0 https://blog.flxxyz.com/technology/2019/firewall-forward-ssr.html#comments https://blog.flxxyz.com/feed/technology/2019/firewall-forward-ssr.html
开箱 涂山蓉蓉手办 https://blog.flxxyz.com/chat/2019/%E7%8B%90%E5%A6%96%E5%B0%8F%E7%BA%A2%E5%A8%98-%E6%B6%82%E5%B1%B1%E8%93%89%E8%93%89.html https://blog.flxxyz.com/chat/2019/%E7%8B%90%E5%A6%96%E5%B0%8F%E7%BA%A2%E5%A8%98-%E6%B6%82%E5%B1%B1%E8%93%89%E8%93%89.html Wed, 20 Feb 2019 18:13:00 +0800 冯小贤 拖延症好严重了,现在时间是2.20,过去了5个星期...
拖延症又犯了...上个星期天(1.20)的文拖到了星期四(1.24)


钱: 预付89 + 尾款478

8.jpg
我蓉开眼了!!!

1.jpg
包装很完整,忍不住要开封了

2.jpg
不用读系列

3.jpg
包的还挺严实的

4.jpg

5.jpg

6.jpg
有点小瑕疵,不影响观感(平时也不会注意到那里)

7.jpg
所有配件展示

]]>
5 https://blog.flxxyz.com/chat/2019/%E7%8B%90%E5%A6%96%E5%B0%8F%E7%BA%A2%E5%A8%98-%E6%B6%82%E5%B1%B1%E8%93%89%E8%93%89.html#comments https://blog.flxxyz.com/feed/chat/2019/%E7%8B%90%E5%A6%96%E5%B0%8F%E7%BA%A2%E5%A8%98-%E6%B6%82%E5%B1%B1%E8%93%89%E8%93%89.html
记一次img转vbox磁盘格式 https://blog.flxxyz.com/chat/2019/img-to-vdi.html https://blog.flxxyz.com/chat/2019/img-to-vdi.html Tue, 22 Jan 2019 15:58:00 +0800 冯小贤 koolshare里面大家好像用的都是StarWind V2V Converter这款软体,再就是用PE里面的写盘工具

然鹅,在macos不能玩这些windows的工具,搜索发现virtual box自带的命令集,真香!

VBoxManage --help一下什么都有,新建,修改,删除,网络适配器,DHCP,共享文件夹...

.img转换.vdi脱离GUI,shell冲冲冲!

$ VBoxManage convertdd openwrt-koolshare-mod-v2.22-r8838-af7317c5b6-x86-64-combined-squashfs.img 1.vdi

一个虚拟机转盘完成,秒转

]]>
0 https://blog.flxxyz.com/chat/2019/img-to-vdi.html#comments https://blog.flxxyz.com/feed/chat/2019/img-to-vdi.html
Golang配置文件热加载 https://blog.flxxyz.com/technology/2019/golang-hot-reload-config.html https://blog.flxxyz.com/technology/2019/golang-hot-reload-config.html Thu, 17 Jan 2019 15:37:00 +0800 冯小贤 最近在捣鼓golang,其中用线上数据全放在redis里,以前写死的配置有点不太适合了,热加载才是王道!

俗话说不会搜索的程序员不是一个好程序员(误

观摩了一下其他大佬的写法,大多都是采用定时器+goroutine实现的。难度不大,开始码

配置文件结构体

假设一下我们的配置文件是json文件,那应该就是下面这样

// conf.json
{
  "host": "127.0.0.1",
  "port": 6379,
  "passwd": "",
  "db": 0
}

首先肯定是要写一个跟它一模一样的结构体出来

//json配置文件结构体
type Content struct {
    Host   string `json:"host"`
    Port   int    `json:"port"`
    Passwd string `json:"passwd"`
    Db     int    `json:"db"`
}

如果继续在此结构体上编写操作函数不太稳妥,序列化json也是直接操作的指针。之前拆散它们的试错,最后还是让它们在一起了233

优化结构体

将文件名,同步锁,最后修改时间,配置文件结构体整合一起

//配置结构体
type Config struct {
    Filename       string
    LastModifyTime int64
    Lock           *sync.RWMutex
    Data           interface{}
}

编写实例配置的工厂函数(这个有点约定俗成的规矩,具体出处你们自己去考证吧,好处挺多的)

func NewConfig(filename string, data interface{}) *Config {
    conf := &Config{
        Filename: filename,
        Data: data,
        Lock: &sync.RWMutex{},
    }

    conf.parse()

    go conf.reload()

    return conf
}

这里把配置结构体配置了默认参数,外部传入参数是配置文件的文件名配置文件结构体,这里data的类型为接口类型,好处是Config可以独立出来,代码多处复用。我们还使用了conf.parse()方法,第一次解析文件,go conf.reload()方法单独起一个goroutine跑(具体效果看后面),结果当然返回本体了

解析函数

暴力读取文件内容,放进json序列化。读文件出错没得商量退群吧你,解json出错返回失败,成功时锁住c.Data写入完成释放

func (c *Config) parse() bool {
    //记录最后修改时间
    fileInfo, _ := os.Stat(c.Filename)
    c.LastModifyTime = fileInfo.ModTime().Unix()

    //读取文件内容
    file, err := ioutil.ReadFile(c.Filename)
    if err != nil {
        log.Println("读取配置文件失败:", err)
        //直接退出程序
        os.Exit(1)
    }

    //解json
    temp := c.Data
    if err = json.Unmarshal(file, &temp); err != nil {
        log.Println("解析json出错:", err)
        return false
    }

    c.Lock.Lock()
    c.Data = temp
    c.Lock.Unlock()
    log.Printf("文件内容 = %+v\n", c.Data)

    return true
}

重载函数

这里新建了个5秒钟的定时器,隔5秒检查最后更改时间,与上次不同就再次解析,修改配置数据

func (c *Config) reload() {
     ticker := time.NewTicker(time.Second * 5)
     for _ = range ticker.C {
          func() {
               fileInfo, _ := os.Stat(c.Filename)
               currModifyTime := fileInfo.ModTime().Unix()
               if currModifyTime > c.LastModifyTime {
                    if c.parse() {
                         log.Println("重新加载配置文件conf.json")
                    }
               }
          }()
     }
}

运行

用着我们最开始使用的配置文件结构体NewConfig()一下,这里要用select {}阻塞一下程序,chan同理,实时的更改conf.json可以直接读到程序里更改了

func main() {
    log.Println("开始运行...")

    data := &Content{
        Host:   "127.0.0.1",
        Port:   6379,
        Passwd: "",
        Db:     0,
    }
    _ = NewConfig("conf.json", data)
    select {}

    //end := make(chan bool, 1)
    //<-end
}

代码

文章里面的演示代码

总结知识点

  1. io操作
  2. 同步
  3. 定时器
  4. 时间
  5. 通道
]]>
3 https://blog.flxxyz.com/technology/2019/golang-hot-reload-config.html#comments https://blog.flxxyz.com/feed/technology/2019/golang-hot-reload-config.html
This page loaded in 0.000938 seconds