豪翔天下

Change My World by Program

0%

  • 使用起来比redux好用多了,就凭这一点我就放弃redux
  • redux将数据保存在单一的store中,mobx则是分散在多个store中
  • react-mobx-typescript-realworld-example-app: 一个很好的example项目

安装配置

  • React集成方式: 注意看里面的Tips,如果不是用的mobx-react-lite,很多东西就不用写了,比如Provider,observable props(不需要在组件外部包裹observer了,默认store变化的时候会自动重新渲染),并且observer自动使用的就是React.memo,不需要单独为了优化性能去useMemo
1
2
3
4
npm install --save mobx
npm install mobx-utils --save # 最好同时安装这个库,提供了更多的帮助方法,例如带参数的computedFn

# 如果实用Typescript或者https://mobx.js.org/enabling-decorators.html可以参考这个文档修改一下配置即可
阅读全文 »

疫情终于结束了,希望今年全国人民各行各业都能缓过来!

2022总结

看了下2021年定的2022年的目标,本以为大多数都没能完成,没想到还是完成了许多的。

阅读全文 »

每年的认知小结

人生

  • 结婚大事已交卷,生娃任务已完成,只要不生病,家人平安健康,慢慢赚钱,其余都是锦上添花。——网络

  • 家总要成,钱总要挣,奔走红尘,勿忘曾经是书生——网络

  • 做人要有责任和担当,应该把钱都拿出来买房,拯救国家经济——网络

  • 努力的意义就是:当好运降临在自己身上时,你会觉得我配,而不是眼看着好事落在别人身上,然后愤愤地说 我呸。——网络

  • 我上了那么多年学,熬了那么多夜,做那么多习题,顶着各种各样的压力,参加各种残酷的考试,谈恋爱,分手,工作,加班。

    我这么辛苦,竟然是为了成为一个普通人——网络

  • 礼物不重要,重要的是礼物背后的心意:我依旧被你重视,被你放在心上。最好的婚姻,不是乍见之欢,而是久处不厌。最好的夫妻,是一起享受生活的平淡,却也喜欢带给对方的惊喜和温暖。

  • 当爱情开花结果,就是另一场冒险的开始。

  • 和你在一起的目的很简单,生个孩子,看你小时候的样子。——老君书屋

  • 即使老婆在自己医院产检我也要陪她去,这样好的消息可以第一时间分享,坏的消息也能第一时间承担。

生活

  • 一个东西的性价比只来自于它的使用频次。——刘飞
  • 当你每次回家,腋窝下面都夹着一些东西,比如妻子的礼物,孩子的礼物,家庭的礼物,那样的话,你会觉得回家,是一种快乐。——涂磊

Xcode常用操作

模拟器打开keyboard键盘

  • 默认是不会弹出键盘的,直接用电脑的键盘进行输入,但是有时候想要调试一下键盘弹出的效果,可以点击顶部菜单I/O -> Keyboard -> Toggle Software Keyboard

Apple设计资源

图标

  • App Icon Generator: iOS或者android各种尺寸图标一键生成,生成后直接拖到xcode即可

App需要提供图标的规格为40/588/60/80/87/120/160/180/1024,另外,如果最好是将png图片转换为jpg,因为默认会把png不存在的地方背景设置为黑色。准备好图标素材以后,直接在xcode里面的Images.xcassets将图标拖入即可。

App 上架流程

  1. 注册开发者账号
  2. App Store Connect新建一个APP
  3. 从Xcode上传APP至App Store Connect
    1. 下载P12文件(申请发布(Distribution)证书)
    2. 导入P12文件(我操作的时候是别人直接发给我的,所以这里就没记录步骤了,应该可以参考这里),有一点需要注意的时候,双击P12文件安装成功后,还需要在keychain里点击其private key,修改Access Control,需要修改配置Allow all applications to access this item,否则下面在上传的时候会提示missing private key或者让你无限输入电脑用户名密码的问题
    3. 点击Product->Archive,完成后会自动弹出一个对话框(当然,这个对话框也可以通过Window->Organizer打开,要选择对应的APP)
    4. 选择Distribute App,然后选择App Store Connect,再Upload,一直下一步应该就可以了。(如果打包能成功,但是上传却说认证失败,可能是网络问题)
    5. 上传完成后可以在App Store Connect后台的TestFlight看到刚才的build了,这时候可以去添加测试用户,点击左侧菜单App Store Connect User进行添加,添加方式见页面提示即可,很简单,添加完成后会发送邮件给用户,里面有个兑换码,在ios的testflightapp上点击redeem输入兑换码即可下载,如果下载时提示the app couldn't be installed because testflight isn't available,那就等大概五分钟试试
阅读全文 »

  • 目前我用到的react-native平台对native支持最好的表格组件了

安装配置

1
2
3
4
5
6
7
8
npm install --save victory
npm install --save victory-native react-native-svg # react-native,注意还需要执行pod install


# react-native需要忽略下面的warning
LogBox.ignoreLogs([
"Require cycle: node_modules/victory",
]);

Charts

VictoryArea

  • 每个横坐标都对应两个纵坐标形成一个area,也可以不提供y0,默认就从y最小值开始
1
2
3
4
5
6
7
8
9
10
11
12
13
<VictoryArea
domain={{x: [minX, maxX], y: [minY, maxY]}} // 可手动设置x和y轴的边界值
domain={{y: [minY, maxY]}} // 也可以单独设置某个轴,和上面的一样,最小值和最大值必须不一样,否则会报一个prop type warning,就只能自己先设置默认值了
data={[
{ x: 1, y: 2, y0: 0 },
{ x: 2, y: 3, y0: 1 },
{ x: 3, y: 5, y0: 1 },
{ x: 4, y: 4, y0: 2 },
{ x: 5, y: 6, y0: 2 }
]}
dataComponent={<Area />} // 指那一块区域而不是某个点
interpolation={'basis'} // 默认是linear折线,basis平滑曲线,其他的其实都有差别,但说不上名字了,可以挨个试试:natural/basis/bundle/cardinal/catmullRom/monotoneY/monotoneX/step(电子信号那种)/stepAfter/stepBefore
/>
阅读全文 »

  • 非常好用的query库,目的是为了缓存后端api的结果,不用像以前一样,手动将结果一个一个存储到store,并且提供了一些非常好用的hook方法
  • 默认支持异步
  • 它并不是用于替代axios等请求库,而只是作为外层的封装,方便控制请求与结果

安装配置

1
npm i @tanstack/react-query

配置就是将其作为一个provider注入到app中

1
2
3
4
5
6
7
8
9
10
const queryClient = new QueryClient()

function App() {
return (
// Provide the client to your App
<QueryClientProvider client={queryClient}>
<Todos />
</QueryClientProvider>
)
}

常用方法hook

useQuery

  • 用得最多的方法,用于获取数据的请求中
  • useQuery如果命中缓存,那么onSuccess这些方法是不会被调用的
  • 默认在以下几种情况下,数据会自动重新获取(即会重新调用请求获取数据)
    • 重新挂载当前组件实例
    • 窗口重新聚焦
    • 网络重新连接
    • 配置了最短refetch时间
  • 需要为不同的请求,设置唯一的key值,如果是带参数的,可以作为数组的第二个参数第三个参数即可,甚至可以是数字、object等对象。
  • 对于enabled=false的请求,如果之前已经缓存过数据了,那么会直接使用缓存的数据,并且status === 'success', isSuccess=true
  • query function要么返回内容,要么抛出错误,不能返回undefined,否则会返回一个warning: query data cannot be undefined
阅读全文 »

安装配置

  • 开发IDE: 我一般就直接用idea了,有solidity插件,但是以太坊有一个官方的IDE: remix

  • 如果是使用hardhat,那么就不用单独安装了,它会安装指定的版本的solc

1
2
3
4
brew update
brew upgrade
brew tap ethereum/ethereum
brew install solidity

语法

  • 可见性修饰符(只能其中一种)

    • public: 任何用户或者合约都能调用和访问
    • private: 只能在本合约内部调用和访问
    • external: 和public类似,不过只能在合约外调用,不能被合约内的其他函数调用
    • Internal: 和private类似,不过可以在继承的子合约中调用副合约的函数
  • 函数修饰符

    • view: 可是使用合约中的变量,只是在本地执行,不会消耗gas,不会修改合约状态(例如修改变量、触发事件等)
    • pure: 只能使用局部的变量,入参或者方法内部的变量,既不读取状态,也不改变状态,同样是本地执行,不会消耗gas
    • payable: 表示一个函数能够附加以太币调用,例如一些需要转账的函数
  • 函数入参修饰符

    • memory: 表示这里是值传递
    • storage: 表示是指针传递
  • 变量分类,注意每个变量在声明时都会有一个对应其类型的默认值(address -> address(0), boolean -> false, enum -> 第一个元素),没有空值null的概念

    • 状态变量:变量值会一直保存在合约的存储空间中
    • 局部变量:仅在函数执行过程中有效,函数退出后就无效了
    • 全局变量:保存在全局命名空间中的变量,用于获取区块链相关信息
  • 内置全局变量

    • block.number(uint): 当前区块号
    • block.timestamp(uint): 当前区块的时间戳,等同于now
    • block.gaslimit(uint): 当前区块的gaslimit
    • msg.sender(address): 消息发送者
    • msg.value(uint): 当前消息的wei值
    • now: 当前区块的时间长
    • tx.gasprice(uint): 当前transaction的gas价格
    • tx.origin(address payable): 当前交易的发送者地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract ERC20Token is ERC20 { // 支持继承
IERC20 token;

uint256 override amount;

mapping (address => bool) public wallets; // 如果要存储一个list并且要判断其是否存在,没有直接的array判断方法,但是可以用这种mapping来实现,wallets[address]=true, requier(wallet[address], '')

struct Transaction { // 创建一个结构体类型
address user;
uint timestamp;
}
Transaction[] transactions; // 数组对象

mapping (address => uint256) public investors; // mapping对象,可以用于记录key value的数据

address public constant MY_ADDRESS = 0x.....; // 产量可以消耗更低的gas

// 继承的时候可以写新的构造函数,并且可以将新的构造函数中的参数传递给父类进行初始化
constructor(uint256 totalSupply, string memory name, string memory symbol, address _anotherToken) ERC20(name, symbol) {
_mint(msg.sender, totalSupply);
token IERC20(anotherToken); // 将另外一个合约作为参数传递进来


transactions.push(
Transaction('xx', 'bbb') // 结构体的初始化
); // 数组默认有一个push方法
}

// 获取当前的sender
function getMsgSender() public view returns(address) {
return msg.sender;
}

function func1(unit amount) {
require(isAllowed[msg.sender], 'Caller not allowed to mint'); // 类似于断言,只有满足前面的条件才行,否则会报错
assert(amount > 123); // 也是断言,但是没有报错信息
}
}
阅读全文 »

salesforce后台配置

  • Lightning Experience就是新版的系统,classic就是老版本,新功能以后都只会出现在Lightning Experience中

常用需求操作方式

导出数据

  • Setup -> Data -> Data Export -> Export Now -> Start Export,大概等个5到10分钟就能在页面下载了

添加navigation菜单到首页

  • Setup -> App Manager ,然后选择自己的首页的app,一般是Force.com,进入编辑页面就能看到Choose the Tabs设置了

跟踪对象或字段的历史修改

  • 首先需要再对象的Details设置里面打开Track Field History

  • 由于每个对象最多只能设置20个追踪字段,所以默认没有打开,针对单独的字段得单独打开,在Object Manage -> Your Object -> Fields & Relationships

    -> Set History Tracking,选中想要追踪的字段保存即可

  • jsforce sdk可以这样查询history

    • 返回的结果中,ParentId才是原始对象的Id,FIeld则是更改的字段
1
2
3
4
5
6
7
// 注意如果是标准对象,那么直接加History即可,例如AccountHistory,如果是自定义对象__c,那么需要将__c替换为__History
conn.sobject('MyCustomObject__History').find({
ParentId: "xxxxxxxxx",
Field: "xxx",
OldValue: "",
NewValue: "",
})

将自定义的对象添加为tab

Sandbox

  • Sandbox的价格表,没错,是按照原始数据的价格来按百分比收费的,怪不得很多用户都只是partial copy,得自己想办法去将生产数据同步到sandbox中去。
  • 如果不用salesforce自己的Refresh方式,那么想要同步production到sandbox,要么借助第三方的收费工具,要么就自己去同步了,自己同步是个体力活,你必须得找到不同对象之间的关系,新插入的数据和之前的ID肯定是不一样的,整个migration程序都得维护这些ID的映射,相当麻烦
  • 注意手动刷新sandbox后,相当于删除旧的创建新的,在旧的sandbox环境里面新建的用户会消失的,新的sandbox的users总是和production的一样,只不过email添加了一个后缀.sandboxname

Apps

  • AppExchange(App Store)里面的app氛围APP、Component、Consultant

Connected App

  • New Connected App 菜单在Apps -> App Manager里面,而不是在Apps -> App Manager -> Connected Apps -> Manage Connected Apps里面

  • App ManagerManage Connected Apps里面如果有相同的app,那么可能这两个菜单点进去会是不同的设置

  • 在设置里面可以设置哪些profile能访问这个app,需要注意的是,即使选择的认证方法是POST的,如果你选择了所有人都能访问app(All users may self-authorize),那么它仍然不会去使用POST认证,会直接用GET去访问app,所以即使我们要所有人都能访问也要选择只允许选择的人(Admin approved users are pre-authorized),你可以选择所有的profile都行(在app最右边下拉Manage菜单中设置,不是View也不是edit)。注意修改后可能出现You don't have permissions to view application with namespace 错误,只需要在manage菜单的下面Profiles那里选择Manage Profiles,把System Administrator打开即可

  • app要允许oauth才能将认证token传到第三方或者自己的callback api

  • 如果要作为tab显示在顶部菜单栏,需要

    • 将connected app的canvas打开,并设置canvas app url

    • 创建visualforce page,里面需要包含这个app,创建一个canvas来包含connected app,例如

      1
      2
      3
      <apex:page standardController="Account">
      <apex:canvasApp applicationName="Connected APP的API名称" width="100%" height="5400px" maxHeight="infinite" />
      </apex:page>
    • 然后在Setup里面搜索Tabs,在visualforce里面选择它,最后再在首页的tabs里面添加即可

  • 创建了带Oauth的app后就能获取到其client_id和client_secret了(也叫Consumer Key和Consumer Secret)

Object & Fields

  • 对象的Record Types只是用于前端可以根据某个值来展示不同的表单,例如根据role来确定admin和user能设置哪些字段
  • __c结尾表示custom__r结尾表示relationship
阅读全文 »

项目配置

  • 默认端口为3000,如果要修改可以在src/main.ts中进行修改
1
2
3
# 项目初始化
npm i -g @nestjs/cli
nest new project-name

.env/dotenv配置文件支持

1
2
3
4
5
6
7
8
npm i --save @nestjs/config

// 然后在app.module.ts中引入即可
@Module({
imports: [ConfigModule.forRoot()], // 如果想要所有modules都能使用可以设置{isGlobal: true}参数
})

process.env.TEST // 使用
阅读全文 »

安装和使用

1
npm install web3 --save
  • web3下面的api是分部在不同的命名空间的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 可以全局用
var Web3 = require('web3');
var web3 = new Web3(Web3.givenProvider || 'ws://some.local-or-remote.node:8546');
const web3 = new Web3(new Web3.providers.WebsocketProvider('WSS_ENDPOINT', {
reconnect: { // 断开重连选项
auto: true,
delay: 5000, // ms
maxAttempts: 5,
onTimeout: false
}
}));
var eth = web3.eth

// 也可以单独用某一个命名空间的
var Eth = require('web3-eth');
var eth = new Eth(Eth.givenProvider || 'ws://some.local-or-remote.node:8546');

// 可以自定义headers
import {HttpHeader} from "web3-core-helpers";
const headers: HttpHeader[] = [{ name: 'token', value: token }];
web3 = new Web3(new Web3.providers.HttpProvider(rpcUrl || '', { headers }));
阅读全文 »