Rust两个小型ORM–Cherry和Akita

Rust使用比较多的ORM是SeaORMDiesel,本文介绍两个轻量级的。

Cherry

https://github.com/bitlabx/cherry

use cherry::{DataSource, PoolConfig};

pub async fn setup() -> Result<(), Box<dyn Error>> {
    let conn = PoolConfig {
        url: "mysql://root:12345678@localhost:3306/foo".to_owned(),
        ..Default::default()
    };

    Foo::setup(conn).await?;

    let result: Option<User> = Foo::select()
        .and_where_eq("id", 123)
        .fetch()
        .await?;

    Ok(())
}

pub struct Foo;

impl DataSource for Foo {}

// You can setup more than one DataSources if you need.
// pub struct Bar;
// impl DataSource for Bar {}

Akita

https://github.com/wslongchen/akita

fn main() {
    let cfg = AkitaConfig::new(String::from("mysql://root:password@localhost:3306/akita"))
        .set_connection_timeout(Duration::from_secs(6))
        .set_log_level(LogLevel::Info).set_max_size(6);
    let akita = Akita::new(cfg).expect("must be ok");
    // CRUD with Entity
    let model = User::default();
    // insert
    let insert_id = model.insert::<Option<i32>, _>(&akita).unwrap();
    // update
    let res = model.update_by_id::<_>(&akita).unwrap();
    // delete
    let res = model.delete_by_id::<i32,_>(&akita, 1).unwrap();
    // list
    let list = User::list::<_>(Wrapper::new().eq("name", "Jack"), &akita).unwrap();
    // page
    let page = User::page::<_>(pageNo, pageSize, Wrapper::new().eq("name", "Jack"), &akita).unwrap();
}

PHP计算PDF页码

使用其他库存在计算不准确和部分压缩文件不支持问题。

安装 pdfinfo

sudo apt install poppler-utils # ubuntu debian
sudo dnf install poppler-utils # centos

安装PHP类

composer require "howtomakeaturn/pdfinfo"

计算代码

$pdf = new PDFInfo('path/to/the/pdf');
echo $pdf->pages;

参考

antd+vue3 开源admin后台

Vue Vben Admin (推荐)

https://github.com/vbenjs/vue-vben-admin

Vue Vben Admin 是一个免费开源的中后台模版。使用了最新的vue3,vite2,TypeScript等主流技术开发,开箱即用的中后台前端解决方案,也可用于学习参考。

特性

  • 最新技术栈:使用 Vue3/vite2 等前端前沿技术开发
  • TypeScript: 应用程序级 JavaScript 的语言
  • 主题:可配置的主题
  • 国际化:内置完善的国际化方案
  • Mock 数据 内置 Mock 数据方案
  • 权限 内置完善的动态路由权限生成方案
  • 组件 二次封装了多个常用的组件

Naive Ui Admin

https://github.com/jekip/naive-ui-admin

Naive Ui Admin 完全免费,且可商用,基于 Vue3.0、Vite、 Naive UI、TypeScript 的中后台解决方案,它使用了最新的前端技术栈,并提炼了典型的业务模型,页面,包括二次封装组件、动态菜单、权限校验、粒子化权限控制等功能,它可以帮助你快速搭建企业级中后台项目, 相信不管是从新技术使用还是其他方面,都能帮助到你。

特性

  • 二次封装实用高扩展性组件
  • 响应式、多主题,多配置,快速集成,开箱即用
  • 最新技术栈,使用 Vue3、Typescript、Pinia、Vite 等前端前沿技术
  • 强大的鉴权系统,对路由、菜单、功能点等支持三种鉴权模式,满足不同的业务鉴权需求
  • 持续更新,实用性页面模板功能和交互,随意搭配组合,让构建页面变得简单化

vue-antd-admin

https://github.com/biubiubiu01/vue-antd-admin

vue-antd-admin基于vue-cli4+vuex+ant-design-vue开发的后台管理系统,包括权限管理,布局方式,国际化,动态路由和后台管理系统常用的table表和表单等功能,包含echarts图的各种展示,第一版已完成,有兴趣可以了解下。

之后可能不咋会更新了,准备写一个vue3+ts+vite了.

vue3-antd-admin

https://github.com/llyyayx/vue3-antd-admin

使用vue3+ant-design-vue+vite+ts开发的通用后台框架,实现了权限系统、动态菜单、表格集成快速使用等功能,简洁干净开箱即用。

vue-admin-better

https://github.com/chuzhixin/vue-admin-better

提供收费版本

  • 40+高质量单页
  • RBAC 模型 + JWT 权限控制
  • 10 万+ 项目实际应用
  • 良好的类型定义
  • 开源版本支持免费商用
  • 跨平台 PC、手机端、平板
  • 后端路由动态渲染

zsh常用插件

plugins=(git composer npm pip pyenv virtualenv debian systemd python history-substring-search zsh-autosuggestions zsh-syntax-highlighting last-working-dir wd extract zoxide)

小程序使用最新版OpenCV教程

本文一步一步教你如何在小程序中使用最新版的OpenCV

安装基础软件

安装基础工具

pacman -S base-devel cmake git

安装以及配置emsdk

git clone https://github.com/juj/emsdk.git
cd emsdk
./emsdk install 2.0.10
./emsdk activate 2.0.10
source ./emsdk_env.sh

配置以及编译OpenCV

进入 https://opencv.org/releases/ 页面下载opencv最新版源码,并解压缩,并进入解压缩后文件夹

取消不需要的OpenCV模块,减少wasm体积

修改platforms/js/opencv_js.config.py文件根据情况,去掉不用的模块

# white_list = makeWhiteList([core, imgproc, objdetect, video, dnn, features2d, photo, aruco, calib3d])
white_list = makeWhiteList([core, imgproc])

配置OpenCV4输出独立的wasm文件

默认OpenCV4会将wasm以base64存到js文件,输出单独wasm文件便于用于微信小程序

打开modules/js/CMakeLists.txt,去掉 SINGLE_FILE参数

# set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s MODULARIZE=1 -s SINGLE_FILE=1")
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s MODULARIZE=1")

配置OpenCV禁用动态执行函数

微信小程序不支持eval()new Function()等动态执行函数,在modules/js/CMakeLists.txt中,增加DYNAMIC_EXECUTION的编译参数屏蔽这些函数的输出

# set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s MODULARIZE=1 -s SINGLE_FILE=1")
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s MODULARIZE=1")
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s DYNAMIC_EXECUTION=0")

查看编译参数

emcmake python ./platforms/js/build_js.py -h

编译OpenCV

emcmake python ./platforms/js/build_js.py build_wasm --build_wasm --build_test

build_wasm\bin目录生成了opencv.js,opencv_js.wasm,tests.html文件

压缩wasm

brotli -o build_wasm/bin/opencv_js.wasm.br build_wasm/bin/opencv_js.wasm

运行以及查看Web测试

npm i -g http-server
http-server build_wasm/bin/

在浏览器打开 http://127.0.0.1:8080/tests.html 可以查看测试结果

修改opencv.js适配微信小程序

修改前先将opencv.js格式化一下,微信小程序不支持通过url获取wasm,修改下instantiateAsync方法的else分支里面的代码,让读小程序项目下的opencv_js.wasm文件


        function instantiateAsync() {
          if (
            !wasmBinary &&
            typeof WebAssembly.instantiateStreaming === "function" &&
            !isDataURI(wasmBinaryFile) &&
            !isFileURI(wasmBinaryFile) &&
            typeof fetch === "function"
          ) {
            return fetch(wasmBinaryFile, { credentials: "same-origin" }).then(
              function (response) {
                var result = WebAssembly.instantiateStreaming(response, info);
                return result.then(
                  receiveInstantiatedSource,
                  function (reason) {
                    err("wasm streaming compile failed: " + reason);
                    err("falling back to ArrayBuffer instantiation");
                    return instantiateArrayBuffer(receiveInstantiatedSource);
                  }
                );
              }
            );
          } else {
            // return instantiateArrayBuffer(receiveInstantiatedSource);
            var result = WebAssembly.instantiate("/opencv/opencv_js.wasm.br", info);
            return result.then(
              receiveInstantiatedSource,
              function (reason) {
                err("wasm streaming compile failed: " + reason);
                err("falling back to ArrayBuffer instantiation");
                return instantiateArrayBuffer(receiveInstantiatedSource);
              }
            );
          }
        }

修改OpenCV.js的imread,imshow,VideoCapture方法支持小程序

这些方法定义在modules\js\src\helpers.js文件中,修改后重新编译和生成wasm文件即可

在小程序使用OpenCV.js

const app = getApp()
WebAssembly = WXWebAssembly;
let cv = require('../../opencv/opencv.js');

Page({
  onLoad: function (options) {
    if (cv instanceof Promise) {
      cv.then((target) => {
        console.log(target);
      })
    } else {
      console.log(cv);
    }
  }
})

参考

C# .net framework不使用命令行或第三方库实现服务安装、卸载、停用,启用

网上资料通常都通过命令行调用sc.exe进行,这里介绍一种通过微软提供API实现的方法。代码更加简单,可控性更好。

使用方法

static void Main(string[] args)
{
    if (args.Length == 0) {
        // Run your service normally.
        ServiceBase[] ServicesToRun = new ServiceBase[] {new YourService()};
        ServiceBase.Run(ServicesToRun);
    } else if (args.Length == 1) {
        switch (args[0]) {
            case "-install":
                InstallService();
                StartService();
                break;
            case "-uninstall":
                StopService();
                UninstallService();
                break;
            default:
                throw new NotImplementedException();
        }
    }
}

ServiceControl 类

 public class ServiceControl
    {
        const string ServiceName = "MyService";

        public static bool IsInstalled()
        {
            using (ServiceController controller =
                new ServiceController(ServiceName))
            {
                try
                {
                    ServiceControllerStatus status = controller.Status;
                }
                catch
                {
                    return false;
                }
                return true;
            }
        }

        public static bool IsRunning()
        {
            using (ServiceController controller =
                new ServiceController(ServiceName))
            {
                if (!IsInstalled()) return false;
                return (controller.Status == ServiceControllerStatus.Running);
            }
        }

        public static AssemblyInstaller GetInstaller()
        {
            AssemblyInstaller installer = new AssemblyInstaller(
                typeof(MyService).Assembly, null);
            installer.UseNewContext = true;
            return installer;
        }

        public static void InstallService()
        {
            if (IsInstalled()) return;

            try
            {
                using (AssemblyInstaller installer = GetInstaller())
                {
                    IDictionary state = new Hashtable();
                    try
                    {
                        installer.Install(state);
                        installer.Commit(state);
                    }
                    catch
                    {
                        try
                        {
                            installer.Rollback(state);
                        }
                        catch { }
                        throw;
                    }
                }
            }
            catch
            {
                throw;
            }
        }

        public static void UninstallService()
        {
            if (!IsInstalled()) return;
            try
            {
                using (AssemblyInstaller installer = GetInstaller())
                {
                    IDictionary state = new Hashtable();
                    try
                    {
                        installer.Uninstall(state);
                    }
                    catch
                    {
                        throw;
                    }
                }
            }
            catch
            {
                throw;
            }
        }

        public static void StartService()
        {
            if (!IsInstalled()) return;

            using (ServiceController controller =
                new ServiceController(ServiceName))
            {
                try
                {
                    if (controller.Status != ServiceControllerStatus.Running)
                    {
                        controller.Start();
                        controller.WaitForStatus(ServiceControllerStatus.Running,
                            TimeSpan.FromSeconds(10));
                    }
                }
                catch
                {
                    throw;
                }
            }
        }

        public static void StopService()
        {
            if (!IsInstalled()) return;
            using (ServiceController controller =
                new ServiceController(ServiceName))
            {
                try
                {
                    if (controller.Status != ServiceControllerStatus.Stopped)
                    {
                        controller.Stop();
                        controller.WaitForStatus(ServiceControllerStatus.Stopped,
                             TimeSpan.FromSeconds(10));
                    }
                }
                catch
                {
                    throw;
                }
            }
        }
    }

参考

建立了一个独立项目交流群

建立了一个"独立项目交流群",本群主要交流开源项目的运作模式和盈利模式。

大家可以在名字前面加地区,以及熟悉的技能,如“长沙-全栈-ning”,名字建议用昵称。

目前还没有项目启动,大家可以想一想,可以先分享一些开源或者商业案例,慢慢形成讨论氛围。

注意:

  • 群永久免费
  • 卖课永久严禁加入
  • HR暂时严禁加入
  • 以前叫做开源项目交流群,后来发现大家可能不一定选择开源,所以就改一下吧

微信扫码进群

独立项目交流群

Windows下PHP安装Imagick扩展

查看本机PHP版本

php -v

输出

PHP 7.4.14 (cli) (built: Jan  5 2021 15:11:43) ( NTS Visual C++ 2017 x64 )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies

可以看到PHP版本为7.4,NTS(非线程安全),64位

下载扩展DLL

  1. 打开 https://pecl.php.net/package/imagick
  2. 找到最新稳定版本,点击后面的DLL
  3. 再打开的页面中,根据上面的PHP版本,选择要下载的DLL

安装

  1. 将下载的压缩文件下的php_imagick.dll放入PHP目录下的ext子目录下
  2. 将压缩文件下的其他DLL文件放到PHP目录
  3. 修改php目录下的php.ini,添加extension=imagick

解决Win10部分程序搜索不到的问题

知乎高分答案是让大家去重装小冰,通常可能是解决不了问题的。

因为情况实际可能是本地应用是以当前用户身份安装的,安装在用户的appdata目录下,然后Windows索引默认排除了用户的appdata目录,所以就搜索不到了。

解决办法:

  • 搜索任意文字,在搜索结果界面,点索右侧三圆点,打开索引选项窗口;

file

  • 在索引选项设置中找到排除目录,将用户的appdata目录从排除目录删除即可。

file

pyenv — 多版本Python(含镜像设置加速下载以及Windows)

安装pyenv

curl https://pyenv.run | bash

显示已安装python版本

pyenv install --list

设置使用镜像

 export PYTHON_BUILD_MIRROR_URL_SKIP_CHECKSUM=1
 export PYTHON_BUILD_MIRROR_URL="https://npm.taobao.org/mirrors/python/"

安装指定版本Python

pyenv install 3.9.9

运行指定版本Python

pyenv global 3.9.9

查看当前已安装和正在运行的Python版本

pyenv versions

查看已安装版本位置

pyenv prefix 3.9.9

windows安装pyenv

管理员身份进入powershell

Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/pyenv-win/pyenv-win/master/pyenv-win/install-pyenv-win.ps1" -OutFile "./install-pyenv-win.ps1"; &"./install-pyenv-win.ps1"

C:\Users\Administrator\.pyenv\pyenv-win\.versions_cache.xml中的所有www.python.org/ftp替换为npmmirror.com/mirrors

安装完以后重新管理员打开powershell

pyenv install 3.10.5

其他

  • pyenv的替代工具是asdf, 可以管理多个语言的版本,包含Python,node,Erlang,Ruby,PHP,Mysql,Postgres等

参考