宝塔Postgresql扩展安装

以pg_stat_statements为例

编译扩展

cd /usr/local/pgsql/contrib/pg_stat_statements/
make && make install

启用扩展

切换为postgres用户sudo su - postgres,运行sql命令行psql,启用扩展

CREATE EXTENSION pg_stat_statements;

修改postgresql.conf

进入宝塔面板,修改postgres配置

shared_preload_libraries= 'pg_stat_statements'

重启postgresql

T0ETF基金

513180 恒生科技
513330 恒生互联网
159941 纳指
513060 恒生医疗
511380 可转债
518880 黄金
513090 证券
159920 恒生
513120 创新药
513500 标普500
513360 教育
513520 日经
162411 油气
513530 红利
159980 有色
513310 半导体
159981 能源化工
513970 消费
159850 国企
513030 德国
164824 印度
161128 标普科技
162719 石油
513080 法国
162415 美国消费
501025 银行

A股重要的ETF

宽基

  • 沪深300 510300
  • 科创版 588000
  • 创业板 159915
  • 上证50 510050
  • 中证500 510500
  • 中证1000 159845

板块

  • 银行 515290
  • 酒 512690
  • 电力 159611
  • 证券 512880
  • 半导体 159995
  • 计算机 159998
  • 医药 512010
  • 医疗 512170
  • 家电 159996
  • 新能源 516160
  • 煤炭 515220
  • 基建 516970
  • 房地产 512200
  • 农业 159825
  • 钢铁 515210
  • 军工 512660
  • 旅游 159766
  • 有色 512400
  • 化工 159870
  • 人工智能 159819
  • 机器人 562500
  • 游戏 159869
  • 大数据 515400
  • 软件 159852
  • 教育 513360

PostgreSQL之json字符字段查找

根据字段值查找

SELECT t.*
FROM table_name t
WHERE json_field->>'type'='5' and  json_field->>'value'!=''

查找并替换

update
table_name d
set cover_content=(cover_content::jsonb || jsonb_build_object('cover_img_id',((select f.id  from file f WHERE  f.path = SUBSTRING(cover_content->>'value',44))  limit 1)::text)::jsonb)
where cover_content->>'type'='5' and  cover_content->>'value'!='' and cover_content->>'cover_img_id' is null;

更新嵌套对象的键值:

如果 jsonb 字段包含嵌套对象,例如:

'{"user": {"name": "Alice", "age": 30}}'

你想更新 user 对象中的 age 为 35,可以使用:

UPDATE your_table
SET jsonb_column = jsonb_set(jsonb_column, '{user,age}', '"35"');

数组里面的字段查找

字段里面存的是数组,数组里面存的对象,可以通过以下语句直接查询对象属性的值

select *
    from cart,
jsonb_array_elements(data::jsonb) as elem where ( elem->>'cover_img_id' is null or  elem->>'cover_img_id'='') order by created_at desc;

数组字段查找并替换

update cart set data= (
  SELECT jsonb_agg(
    CASE
      WHEN element->>'cover_img_url' <> '' THEN jsonb_set(element, '{cover_img_id}',
          ((((select f.id  from file f WHERE  f.path = SUBSTRING(element->>'cover_img_url',44))  limit 1)::text)::jsonb)
          )
      ELSE element
    END
  )
  FROM jsonb_array_elements(data::jsonb) AS element
)
where id in (
    select id
    from cart,
jsonb_array_elements(data::jsonb) as elem where elem->>'cover_img_url' <> '' and ( elem->>'cover_img_id' is null or  elem->>'cover_img_id'='') order by created_at desc
    );

多级数组查找替换

select id                                as cart_id,
       cart_user_id                      as user_id,
       elem ->> 'id'           as file_id,
       (updated_at + interval '30 days') as expired_at
from cart,
     jsonb_array_elements(data::jsonb) as elem
limit 10;

update file f
set expired_at=t.expired_at
from (select id                                as cart_id,
       cart_user_id                      as user_id,
       (elem ->> 'id')::int           as file_id,
       (updated_at + interval '30 days') as expired_at
from cart,
     jsonb_array_elements(data::jsonb) as elem)
         as t
where f.id = t.file_id
  and f.expired_at < t.expired_at;

GoldenDict字典下载以及配置

字典下载

推荐下载:

  • The Little Dict
  • LDOCE 5++ V2.15
  • 牛津高阶英汉双解词典(第9版)
  • 英汉大词典(第2版)

LDOCE 5++配置

自动显示中文

LM5Switch.js

showChineseAll(true); # 在下面两行前增加这一行
// trigger float logo
$(window).scroll();

开启音节默认显示

LM5style.css

.HWD .HYP {
    display: inline-block;
}

参考

数据库究竟存0还是null或者”有标准答案

存0的情况

  • 数值型但是需要统计:比如余额,订单总额

存null的情况

  • 外键可以为空:比如admin_user_id)如果为系统操作,可以为null,这时候存0必须取消数据库约束,或者不建外键约束,都不如存null好

存”的情况

  • 非必填且填写的字符串可以为空字符串:比如外国人的middle name,存”可以方便的拼接full name,这个时候如果不需要拼接,你还是可以存null.
  • 框架不支持修改时自动将null呈现为”,且保存时自动”改为null

Rust图形用户界面(GUI)推荐

iced

A cross-platform GUI library for Rust focused on simplicity and type-safety. Inspired by Elm.


struct Counter {
    // The counter value
    value: i32,
}

#[derive(Debug, Clone, Copy)]
pub enum Message {
    IncrementPressed,
    DecrementPressed,
}

use iced::widget::{button, column, text, Column};

impl Counter {
    pub fn view(&self) -> Column<Message> {
        // We use a column: a simple vertical layout
        column![
            // The increment button. We tell it to produce an
            // `IncrementPressed` message when pressed
            button("+").on_press(Message::IncrementPressed),

            // We show the value of the counter here
            text(self.value).size(50),

            // The decrement button. We tell it to produce a
            // `DecrementPressed` message when pressed
            button("-").on_press(Message::DecrementPressed),
        ]
    }

    pub fn update(&mut self, message: Message) {
        match message {
            Message::IncrementPressed => {
                self.value += 1;
            }
            Message::DecrementPressed => {
                self.value -= 1;
            }
        }
    }
}

Features

  • Simple, easy-to-use, batteries-included API
  • Type-safe, reactive programming model
  • Cross-platform support (Windows, macOS, Linux, and the Web)
  • Responsive layout
  • Built-in widgets (including text inputs, scrollables, and more!)
  • Custom widget support (create your own!)
  • Debug overlay with performance metrics
  • First-class support for async actions (use futures!)
  • Modular ecosystem split into reusable parts:
    • A renderer-agnostic native runtime enabling integration with existing systems
    • Two built-in renderers leveraging wgpu and glow
      • iced_wgpu supporting Vulkan, Metal and DX12
      • iced_glow supporting OpenGL 2.1+ and OpenGL ES 2.0+
    • A windowing shell
    • A web runtime leveraging the DOM

dioxus

Dioxus 是一个可移植的、高性能的、符合人体工程学的框架,使用 Rust 语言构建跨平台的用户界面。

fn app(cx: Scope) -> Element {
    let mut count = use_state(cx, || 0);

    cx.render(rsx! {
        h1 { "High-Five counter: {count}" }
        button { onclick: move |_| count += 1, "Up high!" }
        button { onclick: move |_| count -= 1, "Down low!" }
    })
}

Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应用、TUI程序、等多类平台应用。

如果你能够熟悉使用 React 框架,那 Dioxus 对你来说将非常简单。

独特的特性:

  1. 桌面程序完全基于本地环境运行(并非 Electron 的封装)
  2. 符合人体工程学的设计以及拥有强大的状态管理
  3. 全面的内联文档 – 包含所有 HTML 元素、监听器 和 事件 指南。
  4. 极快的运行效率和极高的内存效率
  5. 智能项目热更新和高效的项目迭代
  6. 一流的异步支持fire
  7. 更多内容请查看 版本发布信息.

tauri

Build smaller, faster, and more secure desktop applications with a web frontend.

Features

  • Desktop Bundler (.app, .dmg, .deb, AppImage, .msi)
  • Self Updater
  • App Signing
  • Native Notifications (toast)
  • App Tray
  • Core Plugin System
  • Scoped Filesystem
  • Sidecar

Security Features

  • localhost-free (:fire:)
  • custom protocol for secure mode
  • Dynamic ahead of Time Compilation (dAoT) with functional tree-shaking
  • functional Address Space Layout Randomization
  • OTP salting of function names and messages at runtime
  • CSP Injection

Utilities

  • Rust-based CLI
  • GH Action for creating binaries for all platforms
  • VS Code Extension

egui

egui: an easy-to-use immediate mode GUI in Rust that runs on both web and native

ui.heading("My egui Application");
ui.horizontal(|ui| {
    ui.label("Your name: ");
    ui.text_edit_singleline(&mut name);
});
ui.add(egui::Slider::new(&mut age, 0..=120).text("age"));
if ui.button("Click each year").clicked() {
    age += 1;
}
ui.label(format!("Hello '{}', age {}", name, age));

yew

A framework for creating reliable and efficient web applications.

use yew::prelude::*;

#[function_component]
fn App() -> Html {
    let counter = use_state(|| 0);
    let onclick = {
        let counter = counter.clone();
        move |_| {
            let value = *counter + 1;
            counter.set(value);
        }
    };

    html! {
        <div>
            <button {onclick}>{ "+1" }</button>
            <p>{ *counter }</p>
        </div>
    }
}

fn main() {
    yew::Renderer::<App>::new().render();
}

slint

Design Goals

We use the following design goals as a guide when developing Slint:

  • Scalable: Run on any screen connected to a device, from desktop computers to low end embedded systems.
  • Lightweight: Fit into a few hundred kilobytes of RAM and require little processing power.
  • Intuitive: Both developers and designers should feel productive and enjoy the design and development process. The APIs should be consistent and easy to use, no matter the target language.
  • Native: Slint apps should match the users’ expectations of a native application. Various target platforms such as embedded devices, desktops, mobile and web should be supported so that both the user and the developer feel comfortable on their platform of choice.

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、手机端、平板
  • 后端路由动态渲染