分类: 全部文章

  • vite项目引入vue3-carousel-3d时添加declare module ‘vue3-carousel-3d’

    vite/vue3中引入vue3-carousel-3d组件时会报错,vue3-carousel-3d是基于vue-carousel-3d改造的,但没有提供types文件。为了解决这个问题,需要在项目中自行添加一个文件,比如命名为vendor.d.ts(可以放在types文件夹,并在tsconfig.json的types数组中添加./types/vendor.d.ts),内容如下:

    declare module 'vue3-carousel-3d';

    这样,就能正常使用了。

  • 博锐剃须刀PS108拆解

    最近新买的博锐剃须刀PS108充电不太足,想打开看看什么原因。但是拆解的时候遇到了麻烦,这个新款结构设计很是奇特,打开了刀头,发现点持仓应该还是从底部充电口的位置才能拆开。

    博锐PS108刀头
    博锐PS108刀头拆解
    博锐PS108充电头

    从底部的外观来看,没有螺丝,应该是用的卡子接口或者螺口,如果是螺口的话,能着力的点就是充电的usb口,拿螺丝刀试着拧了一下,发现不对劲。

    于是,拿美工刀直接从缝里开撬,撬起一个缝就用平头螺丝刀插进去,使劲,就把底部的这个卡片撬下来了。图片上能看到,结构其实不复杂,底片上有个固定充电口的结构,里面电池仓还有很大的空间。

    电池仓是从底部推进去的,有四五个卡子,想取出来,要用垫片把每个卡子都垫好,再往外推。我主要是为了检查一下充电头没有虚焊,确认没有问题,就把问题定位到充电线上去了,换一个头略微大一些(micro头上有弹性结构)的充电线就好了。

    如果以后想换更大的电池,可以考虑把电池仓抠出来,换一个18650进去。

  • Handshaker通过usb连接mac时需要选择PTP模式

    当开启了开发者调试以后,连接模式默认为MTP,mac上打开handshaker但无法连接,切换到PTP模式时,显示已连接,但程序会无响应,也许文件太多了。

  • vue 引进quill-image-resize-module 报错TypeError: Cannot read property ‘imports’ of undefined

    首先说解决方案,不止一个,这里发我觉得比较好的一种。

    在webpack中添加ProvidePlugin,有两种情况。

    webpack.base.conf.js

    如果是vuecli2,则会有./build/webpack.base.conf.js这样的文件,添加方式:

    如果没有引入webpack则需要:

    const webpack = require('webpack')

    找到config下的plugins,添加如下代码:

    plugins: [
       new webpack.ProvidePlugin({
           'window.Quill': 'quill/dist/quill.js',
           'Quill': 'quill/dist/quill.js'
     })
    ]

    vue.config.js

    对于vuecli3,则直接在vue.config.js中找到chainWebpack,添加

    chainWebpack: config => {
        // quill-image-resize-module插件报错imports
        config.plugin('provide').use(webpack.ProvidePlugin, [{
          'window.Quill': 'quill/dist/quill.js',
          Quill: 'quill/dist/quill.js'
        }])
    }

    回过来说一下quill的两种引入方式,一种是直接使用quill,一种是使用vue-quill-editor。

    quill

    <template>
      <div ref="editor"></div>
    </template>
    import 'quill/dist/quill.core.css'
    import 'quill/dist/quill.snow.css'
    import 'quill/dist/quill.bubble.css'
    import Quill from 'quill'
    import { ImageDrop } from 'quill-image-drop-module'
    import ImageResize from 'quill-image-resize-module'
    Quill.register('modules/imageDrop', ImageDrop)
    Quill.register('modules/imageResize', ImageResize)
        data() {
        return {
          quill: undefined,
          currentValue: '',
          options: {
            theme: 'snow',
            bounds: document.body,
            debug: 'warn',
            modules: {
              toolbar: [
                ['bold', 'italic', 'underline', 'strike'],
                ['blockquote', 'code-block'],
                [{ list: 'ordered' }, { list: 'bullet' }],
                // [{ 'script': 'sub' }, { 'script': 'super' }],
                [{ indent: '-1' }, { indent: '+1' }],
                // [{ 'direction': 'rtl' }],
                // [{ size: ['small', false, 'large', 'huge'] }],
                [{ header: [1, 2, 3, 4, 5, 6, false] }],
                [{ color: [] }, { background: [] }],
                // [{ 'font': [] }],
                [{ align: [] }],
                ['clean'],
                ['link', 'image']
              ],
              imageDrop: true,
              imageResize: {}  //注意这里的首字母小写,组件官方文档是大写开头,会报错quill Cannot import ImageResize. Are you sure it was registered?
            },
            placeholder: '书写你的内容',
            readOnly: false
          }
        }
      },
      mounted() {
        this.init()
      },
      methods: {
        init() {
          const editor = this.$refs.editor
          // 初始化编辑器
          this.quill = new window.Quill(editor, this.options)
          // 默认值
          this.quill.pasteHTML(this.currentValue)
          // 绑定事件
          this.quill.on('text-change', (delta, oldDelta, source) => {
            const html = this.$refs.editor.children[0].innerHTML
            const text = this.quill.getText()
            const quillSelf = this.quill
            // 更新内部的值
            this.currentValue = html
            // 发出事件 v-model
            this.$emit('input', html)
            // 发出事件
            this.$emit('change', { html, text, quillSelf })
          })
          // 将一些 quill 自带的事件传递出去
          this.quill.on('text-change', (delta, oldDelta, source) => {
            this.$emit('text-change', delta, oldDelta, source)
          })
          this.quill.on('selection-change', (range, oldRange, source) => {
            this.$emit('selection-change', range, oldRange, source)
          })
          this.quill.on('editor-change', (eventName, ...args) => {
            this.$emit('editor-change', eventName, ...args)
          })
        }
      }

    vue-quill-editor

    <template>
      <div class="hello">
         <quill-editor v-model="content"
                          :options="editorOption"
                          @blur="onEditorBlur($event)"
                          @focus="onEditorFocus($event)"
                          @ready="onEditorReady($event)">
            </quill-editor>
        </div>
    </template>
    
    <script>
    import 'quill/dist/quill.core.css'
    import 'quill/dist/quill.snow.css'
    import 'quill/dist/quill.bubble.css'
    import Quill from 'quill'
    import { quillEditor } from 'vue-quill-editor'
    import { ImageDrop } from 'quill-image-drop-module'
    import ImageResize from 'quill-image-resize-module'
    Quill.register('modules/imageDrop', ImageDrop)
    Quill.register('modules/imageResize', ImageResize)
    
    //自定义字体类型
    var fonts = [
      "SimSun",
      "SimHei",
      "Microsoft-YaHei",
      "KaiTi",
      "FangSong",
      "Arial",
      "Times-New-Roman",
      "sans-serif"
    ];
    var Font = Quill.import("formats/font");
    Font.whitelist = fonts; //将字体加入到白名单
    Quill.register(Font, true);
    
    export default {
      name: 'HelloWorld',
      components: {
        quillEditor
      },
      data () {
        return {
          contentCode:'',
          content: `<p><img src="http://t8.baidu.com/it/u=1484500186,1503043093&fm=79&app=86&size=h300&n=0&g=4n&f=jpeg?sec=1581398243&t=ccf50d7b4dd50dac437d46e368b66b20" width="500"></p>
             `,
         editorOption: {
            modules: {
              toolbar: [
                ['bold', 'italic', 'underline', 'strike', 'image'],
                ['formula', 'clean'],
                ['blockquote', 'code-block'],
                [{'list': 'ordered'}, {'list': 'bullet'}],
                [{'script': 'sub'}, {'script': 'super'}],
                [{'size': ['small', false, 'large', 'huge']}],
                [{ 'font': fonts }],
                [{'header': [1, 2, 3, 4, 5, 6, false]}],
                [{ 'color': [] }, { 'background': [] }],
                [{ 'align': [] }],
                [{'direction': 'rtl'}]
              ],
              history: {
                  delay: 1000,
                  maxStack: 50,
                  userOnly: false
                },
                imageDrop: true,
                imageResize: {
                  displayStyles: {
                    backgroundColor: 'black',
                    border: 'none',
                    color: 'white'
                  },
                  modules: [ 'Resize', 'DisplaySize', 'Toolbar' ]
                }
            },
            placeholder: '输入内容........'
          }
        }
      },
      methods: {
        //vue-quill-editor
        onEditorBlur(quill) {
          // console.log("editor blur!", quill, this.content);
          //this.$emit("editorBlur", this.content);
          this.contentCode=this.content
        },
        onEditorFocus(quill) {
          this.contentCode=this.content
        },
        onEditorReady(quill) {
          // console.log("editor ready!", quill);
        },
        onEditorChange({ quill, html, text }) {
          // console.log("editor change!", quill, html, text);
          this.content = html;
        },
        onEditorChange(quill) {
          // console.log("编辑内容改变!", quill, this.content);
          //this.$emit("editorBlur", this.content);
        },
      },
      mounted() {
        //  console.log("this is current quill instance object", this.editor);
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped lang='scss'>
    </style>
  • 增值税发票开票软件(ukey版)管理员密码留空即可登录

    增值税发票开票软件(ukey版)管理员密码留空

    新开通的ukey,软件据说也是新版的,对照文档发现确实够新,文档跟软件都不太一样,装好开票软件之后,启动,插上Ukey,能识别,输入初始密码88888888,修改初始密码,然后,就是图片上的界面,出来一个管理员用户,还要输入密码,实在不清楚这个管理员是在哪里设置过,于是用ukey密码尝试,密码错误,用初始密码8个8尝试,密码错误,也没有密码找回之类的选项。

    只好拨打12366电话,只有机器人,解决不了问题,甚至连问题都没听懂。

    拨打石景山税务局的电话,电话链路有问题,杂音特别多,说明来意,说电话改了,拨打另外一个,然后打通了说需要去办税大厅,那就去吧。

    去了之后扫二维码预约,扫二维码取号,倒是不用等。

    说明情况之后,姑娘核验了身份证,把ukey交给旁边同事把密码初始化,我插到电脑上再试,还是密码错误,姑娘翻了半天笔记本,说你试试空密码,我把密码清除,点击登录,成功了。这就是经过。一个上午就这么过去了。

  • 在docker中的jenkins中调用composer

    假定部署环境使用的是futuremeng/dnmp(fork自yeszao/dnmp),我在其中增加了一个jenkins,那么当jenkins部署php项目时,除了拉取代码,我还会在shell中修改env为当前实例所需的配置,然后接下来,就是执行composer来构建项目需要的包。之前,我是在jenkins容器中又不得已安装了一个php和composer,这显然是和dnmp下面的php重复了,完全没有必要。

    所以接下来,我查到了在docker-compose.yml的jenkins配置中:

      jenkins:
        image: jenkins/jenkins:${JENKINS_VERSION}
        container_name: jenkins
        volumes:
            - ${JENKINS_HOME_DIR}:/var/jenkins_home
            - ${JENKINS_CERTS_DIR}:/certs/client
            - ${SOURCE_DIR}:/www/:rw
            - ${TOMCAT_WEBAPPS_DIR}:/webapps/:rw
            - /var/run/docker.sock:/var/run/docker.sock
            - /usr/bin/docker:/usr/bin/docker
            - /usr/lib/x86_64-linux-gnu/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7
        ports:
            - "${JENKINS_HTTP_PORT}:8080"
        expose:
            - "8080"
            - "50000"
        privileged: true
        user: root
        restart: always
        environment:
            TZ: "$TZ"
            JAVA_OPTS: '-Djava.util.logging.config.file=/var/jenkins_home/log.properties'
            JENKINS_OPTS: '--prefix=/jenkins'
        networks:
          - default

    设置了

    - /var/run/docker.sock:/var/run/docker.sock

    这一项,其实本来就是为了让容器也能直接调用宿主机的docker命令,我试了一下docker ps -a,真的没问题,那么我就把本来用在宿主机的命令拿过来,比如bash.alias.sample文件中的:

    # php composer
    composer () {
        tty=
        tty -s && tty=--tty
        docker run \
            $tty \
            --interactive \
            --rm \
            --user www-data:www-data \
            --volume ~/dnmp/data/composer:/tmp/composer \
            --volume $(pwd):/app \
            --workdir /app \
            dnmp_php composer "$@"
    }

    将其中的命令改为:

        tty=
        tty -s && tty=--tty
        docker run \
            $tty \
            --interactive \
            --rm \
            --user www-data:www-data \
            --volume /dnmp/data/composer:/tmp/composer \
            --volume /dnmp/www:/app \
            --workdir /app \
            dnmp_php composer install

    其中,我把$(pwd)改为了laravel项目所在的地址,这个地址是宿主机的地址,因为这里的docker命令是宿主机的。另外,/dnmp/data/composer也是对应宿主机中的composer缓存文件夹地址。”$@”则直接写上了install

  • jenkins中通过Global Tool安装nodejs须要注意npm版本可能过低

    初始化jenkins之后,通过Global Tool安装nodejs的某个版本,过高了项目不匹配,跑不通,比如我选择了一个node14.22.0,但依然构建不成功,报错:

    npm WARN read-shrinkwrap This version of npm is compatible with lockfileVersion@1, but package-lock.json was generated for lockfileVersion@2. I'll try to do my best with it!

    以及:

    -  Building for production...
     ERROR  Error: Cannot find module 'html-webpack-plugin'

    后来查到尽管用的是nodejs14,但其中的npm版本低了,用npm -v看了一下是6,其中从第一个报错就应该意识到要升级npm了,所以在shell中加上了:

    npm install -g npm
  • VSCode Remote-SSH使用密码远程的服务器如何保存密码免密登录

    IDE:vscode

    插件:remote-ssh

    场景:远程服务器拿了IP,用户名和密码

    则默认情况下config文件(在远程资源管理器插件中点击修改设置,选择对应的配置文件)中保存为:

    Host 192.168.0.7
      HostName 192.168.0.7
      User root

    每次连接时,都需要用户输入密码,而且重连时也需要输入密码。改善的方式是将登录方式改为密钥的方式。

    在本地电脑上用ssh-keygen生成密钥对,并将公钥放到服务器上去。

    实现的具体步骤:

    本地生成密钥对:

    ssh-keygen -t rsa -f id_rsa_server_someone

    然后将生成的id_rsa_server_someone.pub拷贝到服务器上的/root/.ssh下,并

    cat id_rsa_server_someone.pub >> authorized_keys

    最后,config中修改为:

    Host 192.168.0.7
      HostName 192.168.0.7
      IdentityFile ~/.ssh/id_rsa_server_someone
      PreferredAuthentications publickey
      User root
  • 厦门立林科技对讲机JB2003客户端接线图

    5芯线对讲门铃接线方式如下:
    主机出来的5芯线分别是 红(+V)+12V、白(TXD)数据发送、黑(RXD)数据接收、绿(GND)地线、蓝 (ALM)联网信号,分别对讲分机的排线是 黑、红、黄、绿、白 (+12\ RXD\TXD\GND\ALM ) 如果分机连接的排线不是 黑、红、黄、绿、白 请按照分机的接线柱来接。
    非可视的看它主机是四芯制的还是两芯制,现在新产品非可视大部是两芯制,对哪一楼就接主机的对应接线端与COM公共端口,301的你就一芯接主机的301接线柱另一端接COM公共端口他们不分正负极的。如果是四芯,有一条黑色一般是接COM端,一条黄色接音柱,一条红色接VCC电源,一条接开锁信号的。

  • 关于积水地图

    其实LBS还有很多可以发挥的点,最近聊到了老兵地图,之前我还搞过绘本馆地图、北京露营地地图等。

    最有意义的当属积水地图。

    积水地图

    那时候真好,虽然微博只有两千多粉,但发点东西,这几家地图提供商都很积极响应,高德最快,上线也最快。