萤石云录像机CS-N1-208硬盘报警消除

萤石云录像机CS-N1-208突然间开始连续发出滴滴滴三声蜂鸣,打客服电话问,说可以把报警声关掉。

但检查后发现不只是有报警音的问题,关键是硬盘不转,以为硬盘坏了,换了一个硬盘,依然不转,进入系统,识别不到硬盘。以为主板坏了,打算换一个主板,结果在淘宝上了咨询了一下老板,直接回复是电源的问题,原来的使用的电源是0.7A(12V),远远不够,建议升到2A以上。

于是用一个笔记本电脑的电源(19V)加上一个可调降压模块(12V),开机成功,硬盘也恢复了。

我不理解的是之前它是怎么正常工作的。

顺带备注一下:这个录像机恢复初始密码后,密码是盒子标签上的验证码,区分大小写。网上查到的文档都是说12345,不对。

在ox11以上版本的mac上安装DocuPrint C1110B

DocuPrint C1110B大概是针对中国大陆市场投放的一个打印机型号,目前官方网站已经停止了对这个型号的售后支持,包括驱动下载,即使各种搜索,也只能在非官方网站上找到兼容到ox10的驱动安装包。

一直找到很晚,因为眼睛看花了,误把DocuPrint C1100看成了DocuPrint C1110,所以将错就错在下面这个网址下载了DocuPrint C1100的驱动。

https://www.fujifilm.com/fb/download/eng/docuprint

打开上面的网址,选择相应的型号,点击该型号链接,打开新的页面,切换到mac的tab上,选择想要的系统版本项,打开的是一个日文的页面,没关系,用一下翻译插件,点击同意并下载,在mac上打开这个驱动并安装。

在usb上连接上打印机,并开机,添加打印机,这个时候如果还是没有显示打印机型号,显示为普通的PLC打印机,则选择其他,然后定位到系统盘的“资源库-Printers-PPDS-Contents-Resources-FX DocuPrint C1100”即可添加成功。

第二天再仔细看才发现具体型号是DocuPrint C1100,到官网查看了一下产品照片,其实和DocuPrint C1110一样,那么用的芯片实际上也是一样的了。在武汉的时候修打印机的师傅告诉我,打印机虽然那么多型号,但实际上芯片规格并不多,很多很神奇的联想方正打印机,直接到日本打印机官网去下载某型号的驱动就可以用,因为都是贴牌或套壳的。

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';

这样,就能正常使用了。

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

替换vant加载的外部资源来避免nginx策略屏蔽

某项目因前置nginx限制较多,不允许站内调用外部资源,所以因vant引用了cdn的图标,以及通过data方式加载图标资源,需要对vant进行修改,但又不想去自己弄个vant的修改版,所以从build之后的文件入手。

先创建一个localFilterPlugin.js,放在src/libs内,或者其他文件夹,比如utils,看你的习惯。内容如下:

/*
 * @Date: 2021-11-26 15:43:28
 * @LastEditors: Future Meng
 * @LastEditTime: 2021-11-26 18:19:11
 */
// 用于向控制台输出带颜色的问题提示
const fs = require('fs') // node的文件系统模块,用于读取操作系统文件
const path = require('path') // node提供的一些用于处理文件路径的工具
const chalk = require('chalk')

class LocalFilterPlugin {
  static defaultOptions = {
    filenameReg: /^chunk-mobile\..*\.css$/,
    originContent: /@font-face[^}]+}/g,
    newContent: '',
    assetsPath: '../../dist/css'
  };

  constructor(options = {}) {
    this.options = { ...LocalFilterPlugin.defaultOptions, ...options }
  }

  apply(compiler) {
    const _this = this
    compiler.plugin('done', function(compilation, callback) {
      const filePath = path.resolve(__dirname, _this.options.assetsPath)

      fs.readdir(filePath, (err, files) => {
        // 读取文件路径
        if (err) {
          console.log(chalk.yellow('读取文件夹异常:\n' + err.message + '\n'))
        }
        files.forEach((filename) => {
          // 找到符合正则规则的文件
          if (_this.options.filenameReg.test(filename)) {
            // 读取该文件
            const fileDir = path.resolve(filePath, filename)
            fs.readFile(fileDir, 'utf-8', (err, data) => {
              // 读取文件内容
              if (err) {
                console.log(chalk.yellow('读取文件异常:\n' + err.message + '\n'))
                return
              }

              // 替换文件内容
              const result = data.replace(_this.options.originContent, _this.options.newContent)
              fs.writeFile(fileDir, result, (err) => {
                if (err) {
                  console.log(chalk.red('写入修改后的文件异常:\n' + err.message + '\n'))
                  return
                }
                console.log(chalk.cyan(filename + '替换完成'))
              })
            })
          }
        })
      })
    })
  }
}

module.exports = LocalFilterPlugin

然后在vue.config.js中添加对这个自定义插件的引用。

const LocalFilterPlugin = require('./src.mobile/libs/localFilterPlugin')

module.exports = {
        configureWebpack: config => {
    const configNew = {}
    if (process.env.NODE_ENV === 'production') {
      configNew.externals = externals
      configNew.plugins = [
        // 构建后剔除@font-face
        new LocalFilterPlugin({
          options: {
            filenameReg: /^chunk-mobile\..*\.css$/,
            originContent: /@font-face[^}]+}/g,
            newContent: '',
            assetsPath: '../../dist/css'
          }
        })
      ]
    }
    return configNew
  },
}

就这些。

参考资料:https://blog.csdn.net/qq_31968791/article/details/102900349