关于vueuuid的信息
vue3 实现 select 下拉选项
本人学生 , 平时在外面没事接点小项目小赚一笔补贴生活费. 之前一直都是使用 Vue2.x 的版本做项目, 暑假刚刚学习了 Vue3 想着新项目就直接用 Vue3 上手.
好了, 话不多说先给大佬们看看效果样式:
因为下拉框可能会在某些情况下被挡住, 所以这里的下拉框被挂载到了 body 标签上, 并且下拉框中的选项往往是以 slot 插槽的形式编写, 这里就会困扰到很多小白, 搞不明白怎么样才能在 下拉框 与 触发下拉按钮 之间关联响应式事件与数据.
tk-select 为 select 下选项父标签, 必须含有插槽 #selectDropDown 才能正常使用
tk-select-item 为**select
**下选项子标签(选项标签), tk-select-item 内可以继续写入其他 HTML 内容, 每项的具体值由props value 决定
可以使用 v-modal 实时获取到 下拉选项 选取到的值
首先看看目录结构
两个 .vue 文件用来的干嘛的没什么好说的, selectBus.js 解决 Vue3 中无法安装 eventBus 的问题, token.js 用于给每组 selec t 与 select-item 相互绑定.
我们先看看 vue3 官网怎么说的 进入官网 . 说人话的意思就是不可以像 vue2 那样愉快的安装 Bus , 需要 自己实现事件接口 或者使用 第三方插件 . 这里官网也给出了具体实现方案.
vue3 新增 teleport 标签, 可以将标签内的元素挂载到任意位置, 查看官方文档
select 主要有触发下拉按钮 tk-select-button 和下拉列表 tk-select-dropdown 组成, 下拉框中的选项未来将由插槽插入.
首先解决下拉列表打开关闭和定位的问题
在 select.vue 中接收事件
到这里下拉选项框基本就完成了. 我们像页面添加第一个下拉选项时非常完美,但是如果页面上有两个 select 存在时问题来了. 我们发现当控制其中一个选项被选中是, 另外一个 select 显示的值也随之改变. 我们需要将一组 select select-item 进行绑定,让 Bus 在接受时知道事件来自于哪个里面的 select-item .
在 vue2 中我们通常获取实例的 parent 然后一层一层寻找父类 select , 但是在 vue3 setup 中并不能获取到正确的 parent , 所以我想到了可以在 select 创建时派发一个 token 在讲此令牌传给所有子类, 好了理论存在, 开始实践.
在vue中使用 provide 可以向子类、孙类等等后代传输数据, 后代使用 inject 接收数据. 查看官网
这里可以模仿Java中的UUID
在 select 创建时生成 token 并派发给后代
这样我们在子类接收后每次使用 bus 发送数据时带上 token
在 select.vue 监听Bus后先验证token
github.com/18651440358/vue3-select
第一次写帖子几分激动几分不知所措, 请各位大佬指点错误或可以优化的地方, 欢迎大家讨论.

ansyseplot在哪
一、学会使用Help
1、如果你的ANSYS?HELP不能打开,或者打开后内容为空,请单独下载并安装ANSYS?HELP,安装路径选择和ANSYS的安装路径一致。ANSYS19.0;ANSYS19.1;ANSYS19.2?HELP文件下载地址:
链接:
提取码:help
2、使用HELP强烈建议要了解ANSYS?经典界面的操作,这样可以从经典界面的操作中定位到HELP,进而找到相关的命令帮助。如创建模型的一个关键点,在ANSYS经典界面中的操作如下
在这里插入图片描述
点击对话框中的HELP按钮,即可自动定位到该功能的命令帮助
在这里插入图片描述
由上面的HELP可知,创建关键点的命令是K
3、APDL的相关命令,既可以通过搜索直接搜索,也可以在Mechanical?APDL—?Command?Reference目下根据命令的首字母进行查找
在这里插入图片描述
4、以*get命令为例(APDL的命令不区分大小写),介绍如何查看APDL的HELP帮助
首先,查找?get命令,可以直接通过首字母查找,也可以通过搜索进行查找
在这里插入图片描述
在这里插入图片描述
从帮助文档中我们可以看到get命令是做什么的(获取某些值并存储在参数中),它有哪些具体参数,以及各个参数的意义。
向下翻,找到前处理需要获得值的模块
在这里插入图片描述
比如我们想要获得前处理阶段,关键点的相关值,我们可以点击Entity=KP,定位到相关帮助
在这里插入图片描述
在这里插入图片描述
如Item1=LOC,IT1NUM=X,就可以获得关键点N的X坐标值。具体命令如下
*get,kp,n,loc,x??!(其中n为具体的关键点编号)
再如,N=0或者空,Item1=NUM,IT1NUM=MAX,就可以获得关键点的最大编号值
在这里插入图片描述
具体命令如下
*get,kp,,num,max
二、DO和IF命令
1、*DO命令的HELP
在这里插入图片描述
使用命令格式如下
*do,i,1,6??!?i从1-6循环
....
*enddo
2、*IF命令的HELP
在这里插入图片描述
使用命令格式示例如下
*if,a,eq,6??!?如果a=6
...
*elseif
...
*endif
if操作符有以下几种,具体可以看HELP
在这里插入图片描述
三、APDL常用函数命令(点到为止,具体使用方法参照HELP)
1、材料定义
MP:将材料的线性性质定义为温度的常数或函数。
TB:激活材料属性或特殊元素输入的数据表。定义非线性材料本构模型。
2、选择命令
*sel选择族
asel:选择面
vsel:选择体
ksel:选择关键点
nsel:选择节点
lsel:选择线
allsel:全部选择
3、其它辅助命令
gplot:各元素综合显示
kplot:显示选择的关键点
lplot:显示选择的线
aplot:显示选择的面
vplot:显示选择的体
nplot:显示选择的节点
eplot:显示选择的单元
/eshape:显示形状由实际常量、节定义或其他输入决定的元素。
nummrg:合并重合或等价定义元素。
numcmp:压缩定义的编码(重新编号,空的数字补上)
kdist:查询两个关键点之间的距离
ndist:查询两个节点之间的距离
cm:组件为一个新的集合
cmdele:删除一个集合
cmsel:选择一个集合
4、格网划分命令
属性分配
*att命令族(k,l,a,v)
katt:将属性与选中的、未网格化的关键点关联起来。
latt:katt:将属性与选中的、未网格化的线关联起来。
aatt:katt:将属性与选中的、未网格化的面关联起来。
vatt:katt:将属性与选中的、未网格化的体关联起来。
大小控制
*esize命令族(l,a,d,k)
esize:指定默认的行分割数。
lesize:指定未网格线的分割和间距比。
aesize:指定要在区域中网格化的元素大小。
desize:控制默认单元的大小
kesize:指定最接近关键点的元素的边长。
划分网格
*mesh命令族(k,l,a,v)
amesh:在面域内生成节点和面要素
lmesh:沿着先生成节点和线要素
kmesh:在关键点上生成节点和点要素
vmesh:在体中生成节点和体要素
vsweep:Fills?an?existing?unmeshed?volume?with?elements?by?sweeping?the?mesh?from?an?adjacent?area?through?the?volume.
网格清除
*clear(k,l,a,v)
5、荷载与约束
fk:定义关键点处的力荷载
fkdele:删除关键点出的集中力
f:指定节点处的力荷载
fdele:删除节点处的集中力
sfl:在指定线上施加面荷载
sfldele:删除线上的均布荷载
sfa:在选择的面上施加面荷载
sfadele:删除面上的均布荷载
sf:在指定节点上施加面荷载
sfdele:删除节点上的面荷载
sfe:在指定单元上施加面荷载
sfedele:删除单元上的均布荷载
dl:对指定的线约束
dldele:删除线约束
dk:对指定的关键点约束
dkdele:删除关键点约束
da:对指定的面约束
dadele:删除面约束
d:对指定的节点的约束
ddele:删除节点约束
acel:重力加速度荷载施加
dtran:将几何模型的约束转换为有限元模型的约束
ftran:将几何模型的集中力转为有限元模型的荷载
sftran:将几何模型的均布荷载转为有限元模型的荷载
lsclear:清除指定类型的荷载
6、求解通用设置
在这里插入图片描述
7、后处理命令
在这里插入图片描述
在这里插入图片描述
四、APDL常用功能命令
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
五、学会使用数组
1、数据定义命令
在这里插入图片描述
在这里插入图片描述
2、数据删除
在这里插入图片描述
3、数组赋值
在这里插入图片描述
4、数组查看
在这里插入图片描述
5、时间历程变量赋值给数组
在这里插入图片描述
六、数据的读入和写出
1、数据读入基本格式
在这里插入图片描述
示例代码
finish
/clear
/prep7
*create,dataRead,mac?!创建宏文件
*dim,read_Data,,6,5?!定义二维数组(i=6,j=5)
!===============无论按列还是按行写入数组,都要保证i对应的是6,j对应的是5
!*vread,read_Data(1,1),data,txt,,ijk,6,5?!(按列写入数组)读取data.txt文件数据至read_Data数组
*vread,read_Data(1,1),data,txt,,jik,5,6?!(按行写入数组,和原始数据保持一致)
(5f3.0)?!定义数据格式-----每行读取5个数据,每个数据共有3位数,其中小数点位数为0
*end
dataread?!运行宏文件
*status,read_Data
在这里插入图片描述
2、数据写出基本格式
在这里插入图片描述
示例代码
finish
/clear
/prep7
!自定义数组并填充值
*dim,writeData,,20,5
*do,i,1,20
*do,j,1,5
writeData(i,j)=5*(i-j)+j
*enddo
*enddo
*create,dataWrite,mac?!创建宏文件
*cfopen,data1,txt?!创建写出文件
*do,i,1,20
*vwrite,writeData(i,1),writeData(i,2),writeData(i,3),writeData(i,4),writeData(i,5)
(5f8.2)?!定义数据格式(每行写5个数据,每个数据共有8位(包括小数点),其中小数点后有2位)
*enddo
*cfclose
*end
datawrite?!运行宏文件
七、不带参和带参宏文件的创建
1、不带参宏文件创建命令
在这里插入图片描述
2、不带参宏文件的基本格式
在这里插入图片描述
3、带参宏文件的创建(程序编写和不带参的一样,只是一些需要外部输入的参数用指定的参数名arc1~19代替)
在这里插入图片描述
八、制作自定义工具条
在这里插入图片描述
ANSYS?APDL入门教程
相关文章
react?hooks?防抖函数
防抖的意思就是用户输入的时候不会频繁请求接口,一旦用户停下来在设定的时间内都没有再输入,那就可以发送请求,所以这样就减少了请求防抖这个用hooks有点小麻烦,主要是要获取input传入的参数event.persist(),这个是要加上的,不然会报一个警告,如下图所示:翻译一下就是:…...
2022/4/18?15:04:40
hive从第一个表insert?overwhite数据到另一张表根据半自动分区覆盖
删除并清除第一张表?drop?table?test.dxp_qgm_hbase_linshi_01?purge;?第一张表的建表sql?CREATE?EXTERNAL?TABLE?test.dxp_qgm_hbase_linshi_01?(?test_int?int,?gupiaoid?string?)?PARTITIONED?BY(hdfs_par?string)?STORED?AS?PARQUET?LOCATION?‘hdfs://nameservice2/htdata…...
2022/4/18?15:04:33
Jmeter?阶梯线程组
文章目录背景场景Jmeter?实施步骤?背景?什么是实际的性能测试????1)思考时间:用户在做不同操作之间有时间停顿,或者延迟,思考时间就是模拟用户的操作过程中的停顿的间。?2)步伐,速度:主要包括,大量用户进来的时间和退出时间,控制迭代之间的时间,例如,现场用户20个…...
2022/4/18?15:04:24
百度经验如何引流?百度经验的引流技巧
什么是百度经验??百度体验是百度于2010年10月推出的一种新的生活知识产品。它主要解决用户的“具体怎样做”,并着重解决实际问题。在体系结构方面,它集成了百度已知的问题和百度百科的格式标准。百度经验是可以指导人们达到特定目的的文章,通常包括:概述,工具/原始资料,…...
2022/4/18?15:04:17
什么是代理服务,如何选择最佳IP代理?
什么是代理服务,如何选择最佳IP代理??代理IP已经越来越成为了网络高频词语,因为我们的工作和生活中对代理IP的需求越来越多了,代理IP的应用场景也越来越广泛。那么,对于一些刚开始认识代理IP的朋友来说,什么是代理服务呢?如何选择最佳的IP代理呢?什么是代理服务?在英语…...
2022/4/18?15:04:10
powerdesigner16.5逆向生成数据库表结构
powerdesigner是一款数据库建模工具,可以用来生成数据库模型,也可以反向生成表结构,保存为word。?你编写表结构文档时候是自己一个字一个字敲得吗?如果这样效率就太低了,如果有很多表会把你逼疯了。如果使用这个工具反向生成表结构文档,就能节省n多时间。?首先,我们需要…...
2022/4/18?15:04:04
2.1?登录功能
文章目录?登录功能:后台在登录成功之后,需要将当前的用户信息和当前的用户所拥有的权限表达式共享到session中(在权限校验中需要使用)获取session的方式:RequestContextHolder?/?RequestContextListener监听器:?作用域监听器:监听作用域对象(request/session/applicati…...
2022/4/18?15:03:57
请按照以下要求设计一个学生类Student,并进行测试,要求如下:
请按照以下要求设计一个学生类Student,并进行测试,要求如下:?(1)Student类中包含姓名、成绩两个属性。?(2)分别给这两个属性定义两个方法,一个方法用于设置值,另一个方法用于获取值。?(3)Student类中定义一个无参的构造方法和一个接收两个参数的构造方法,两个参数分…...
2022/4/18?15:03:51
软件测试——解析各种覆盖率的含义
语句覆盖:每条语句至少执行一次。判定覆盖:每个判定的所有可能结果至少出现一次。(又称“分支覆盖”)条件覆盖:每个条件的所有可能结果至少执行一次。判定/条件覆盖:一个判定中的每个条件的所有可能结果至少执行一次,并且每个判断本身的所有可能结果至少执行一次。多重条…...
2022/4/18?15:03:44
今日ADB学习记录
今天使用了几个ADB命令,写个文章巩固一下。?adb?devices?//查看连接的设备?adb?shell?screencap?-p?/sdcard/1.png?//截屏储存在sdcard中?adb?pull?/sdcard/1.png?e:\?//从sdcard拉取1.png文件到e盘?adb?push?e:\2.png?/sdcard/?//从e盘发送2.png文件…...
2022/4/18?15:03:37
记录一下使用javamail遇到的问题
今天使用了JAVAmail遇到了javax.mail.AuthenticationFailedException:?Unable?to?log?on?at?com.sun.mail.pop3.POP3Store.protocolConnect错误,明明用户名和密码是正确的,但就是不能登陆上去,最后发现可以通过授权码登录,也就是把密码改成授权码就可以登录成功了。163邮箱…...
2022/4/18?15:03:31
Expectation?2020杭电hdu多校第6场
与运算显然按位考虑,每次把当前枚举位i为1的边全部拿出来,那么这一位的总贡献就是2^i*生成树数量,生成树数量可以用矩阵树定理算出来。最后把每一位的贡献加起来,除以所有边算出来的生成树数量。#includebits/stdc++.h?using?namespace?std;?const?int?mod=9982443…...
2022/4/18?15:03:25
Java中通过mapper.xml控制只查询年月日或者时分秒
Java中通过mapper.xml控制只查询年月日或者时分秒?DATE_FORMAT(字段,%H:%i:%s)?=?DATE_FORMAT(?#{字段,?jdbcType=VARCHAR}?,%H:%i:%s)?这里我是通过mysql函数来进行控制的##?DATE_FORMAT()?函数用于以不同的格式显示日期/时间数据。mysql函数具体使用详情?**再记录两个知识…...
2022/4/18?15:03:18
《算法笔记》2.5小节_习题6-4?有序插入
题目描述:?有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入到数组中。?假设数组长度为10,数组中前9个数(这9个数要求从键盘上输入,输入时要满足自小到大的输入顺序)已经按从小到大进行排序。?然后再从键盘上输入一个整数,将此整数插入到前有序的9个数…...
2022/4/18?15:03:12
【Python-opencv篇】?bitwise_and、bitwise_not等图像基本运算及掩膜
1.图像基本运算图像的基本运算有很多种,比如两幅图像可以相加、相减、相乘、相除、位运算、平方根、对数、绝对值等;图像也可以放大、缩小、旋转,还可以截取其中的一部分作为ROI(感兴趣区域)进行操作,各个颜色通道还可以分别提取及对各个颜色通道进行各种运算操作。总之,…...
2022/4/18?15:03:03
【剑指Offer】11.?旋转数组的最小数字
题目描述?把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。解题思路?将旋转数组对半分可以得到一个包含最小元素的新旋转数组,以及一个非递减排序的数组。新的旋转数组的数组元素是原数组的…...
2022/4/18?15:02:57
当运行时报?There?is?already?‘erpCustomerStaffCultivatePlanController‘?bean?method
当运行时报?There?is?already?‘erpCustomerStaffCultivatePlanController’?bean?method(已经有了’?erpcustomerstaff栽培ateplancontroller?’?bean方法)1.在报错处可以看到是那两个类的错2.问题原因?:两个Controller的@RequestMapping中的路径写成一样的了解决方法:将它…...
2022/4/18?15:02:50
贵州天下众合的商业运作模式
每个国家经济飞速发展的时期,总是会存在一些遗留问题。中国在经历了改革开放后的经济大发展,综合国力得到了极大的增强,但是现如今其存在的问题也暴露无遗。市场经济进入发展瓶颈期,经济发展动力严重不足,企业的大规模不动产投资也造成了资金流动性变差,产生了大量不良资…...
2022/4/18?15:02:43
类加载二:常量的值并非编译期间可以确定的,则不会放入常量池,引用常量会导致类的初始化
二、常量的值并非编译期间可以确定的,则不会放入常量池,引用常量会导致类的初始化。代码如下:public?class?MyTest03?{public?static?void?main(String[]?args)?{System.out.println(MyParent03.str);}}class?MyParent03?{public?static?final?String?str?=?UUID.randomUUID…...
2022/4/18?15:02:37
Excel学习二
一页纸打印?方法一?右下角分页预览拖动边框变一页?方法二?选好位置?打印选中的部分自定义缩放到一页按列拆分数据到多个sheet?如图所示把所有数据按性别拆分成两个工作簿性别添加到筛选字段选中数据透视表分析页-数据透视表-选项-显示报表筛选页即可自定义文本格式选中?Ctrl+1,…...
2022/4/18?15:02:30
最新文章
实验3.1?简单实现Intent带返回值的跳转
在这里实现的功能是当点击listview的某一子项是,启动一个确认删除相应记录的子Activity。?所以用到了带返回值的intent?父界面和子界面的前台代码?activity_main??xml?version"1.0"?encoding"utf-8"??LinearLayoutxmlns:android…...
2022/5/12?22:08:31
JQuery快速入门-选择器
JQuery选择器?JQuery?选择器继承了CSS?与Path?语言的部分语法,允许通过标签名、属性名或内容对DOM?元素进行快速、准确的选择,而不必担心浏览器的兼容性,通过jQuery?选择器对页面元素的精准定位,才能完成元素属性和行为的处理。?一…...
2022/5/12?22:08:23
网页设计工具
下载地址:转载于:...
2022/5/12?22:08:14
事件总线模式辨析
事件总线定义:事件总线是对发布-订阅模式的一种实现。它是一种集中式事件处理机制,允许不同的组件之间进行彼此通信而又不需要相互依赖,达到一种解耦的目的。?事件总线的处理流程:?发布订阅模式主要有两个角色:?发布方…...
2022/5/12?22:08:06
在虚拟机上安装redis集群,redis使用版本为4.0.5,本机通过命令客户端可以连接访问,外部主机一直访问不了...
在虚拟机上安装了redis?4?,启动后本机客户端可以连接访问,但是外部主机一直访问不了,在使用java代码连接redis集群时报:no?reachable?node?in?cluster,原因:在redis3.2.0版本以后redis.conf配置文件中增加了protected-mode保护模式…...
2022/5/12?22:07:59
Spring(十九):Spring?AOP(三):切面的优先级、重复使用切入点表达式
背景:?1)指定切面优先级示例:有的时候需要对一个方法指定多个切面,而这多个切面有时又需要按照不同顺序执行,因此,切面执行优先级别指定功能就变得很实用。?2)重复使用切入点表达式:…...
2022/5/12?22:07:52
20165221?实验五?网络编程与安全
实验封面?课程:Java程序设计班级:1652班姓名:谭笑学号:20165221指导教师:娄嘉鹏实验日期:2018年5月28日实验时间:15:25?-?17:15实验序号:实验五实验名称:网络编程与安全?…...
2022/5/12?22:07:44
Springboot第二篇:与前端fetch通信(附springboot解决跨域方法)
说到与前端通信,明白人都知道这章肯定会写两部分的东西啦。?关于后台?①首先回顾前文,上一章环境搭建如图:?②我们在maven.example.controller下添加一个文件,并附上如图代码:?③:上面又多出了两个注解…...
2022/5/12?22:07:37
VMware12提示?已将该虚拟机配置为使用?64?位客户机操作系统。但是,无法执行?64?位操作...
VMware12提示?已将该虚拟机配置为使用?64?位客户机操作系统。但是,无法执行?64?位操作。此主机支持?Intel?VT-x,但?Intel?VT-x?处于禁用状态解决办法:下载LeoMoon?CPU-V?检查一下CPU?VT-x状态是否启用地址:…...
2022/5/12?22:07:30
[UE4]子控件Child?Widget顶层容器选择
如果父级容器是Canvas,则可以直接设置尺寸。放到其他widget的时候也会保持设定好的尺寸(而不管父容器是什么类型)。?转载于:...
2022/5/12?22:07:21
用Vue来实现购物车功能(二)
这个小demo具有添加商品进购物车?、增加购物车内商品的数量、减少购物车内商品的数量、计算一类商品的总价、以及计算所有商品的总价?首先看目录结构?因为我们的Tab.vue?Car.vue?以及Carinfo.vue中的数据有关联?所以用到了vuex?在store文件夹下的index.js中?import?Vue?from…...
2022/5/12?22:07:09
列表和字典循环遍历时的删除问题,集合
1.for?循环的问题?:?for?循环后面也有else,也可以使用break和continue(使用方法跟while一样).?while?条件:?for?变量?in?迭代器:?循环体?代码块?else:?else:?代码块?…...
2022/5/12?22:07:02
loadrunner中并发数与迭代的区别
loadrunner中并发数与迭代的区别?网友问题:?例如在LR里,我要测100个用户同时并发登陆所用时间,那我是不是在录制好脚本后,需要参数化“用户名”,“密码”以及在那个记事本里构造100个真实的用户名和密码??然…...
2022/5/12?22:06:52
分区分表(一)
一、概念?1.为什么要分表和分区?日常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表。这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情况am…...
2022/5/12?22:06:45
各类型数据的导入与导出
*******?导出到excel?exec?master..xp_cmdshell?bcp?settledb.dbo.shanghu?out?c:\temp1.xls?-c?-q?-s"gnetdata/gnetdata"?-u"sa"?-p""/***********?导入excel?select?*?from?openrowset(microsoft.jet.oledb.4.0,?excel?5.0;hdryes;database?c…...
2022/5/12?22:06:38
zookeeper?安装及集群
一、zookeeper介绍?zookeeper是一个中间件,为分布式系统提供协调服务,可以为大数据服务,也可以为java服务。?分布式系统,很多计算机组成一个整体,作为一个整体一致对外并处理同一请求,内部每台计算机都可以…...
2022/5/12?22:06:31
关于HashSet
HashSet存储数据原理:当HashSet调用add方法时,有返回值,返回值是boolean类型,表示是否添加成功(如果对象不存在,则添加成功,否则添加失败)但是,添加的过程并不是一个个去…...
2022/5/12?22:06:25
【dp?贪心】bzoj4391:?[Usaco2015?dec]High?Card?Low?Card
巧妙的贪心?Description?Bessie?the?cow?is?a?huge?fan?of?card?games,?which?is?quite?surprising,?given?her?lack?of?opposable?thumbs.?Unfortunately,?none?of?the?other?cows?in?the?herd?are?good?opponents.?They?are?so?bad,?in?fact,?that?they?always?play?in?a?com…...
2022/5/12?22:06:18
HTML?选择目录
input?type"file"?webkitdirectory?directory?multiple/?转载于:...
2022/5/12?22:06:10
Bootstrap?学习笔记4?巨幕页头略缩图警告框
转载于:创作挑战赛新人创作奖励来咯,坚持创作打卡瓜分现金大奖...
租机械用什么软件
装载机。也就是58同城,赶集网,百姓网这些软件,或者看看本地的生活网站!
微信支付后端篇
微信支付系列文章
微信支付-java后端实现
微信支付-vue 前端实现
java demo: 下载地址文章底部
技术栈
Spring boot
java
XML (微信在http协议中数据传输方案)
MD5 签名
微信支付术语
openid (OpenID是公众号一对一对应用户身份的标识)
app_id (公众号id,登录微信公众号–开发–基本配置中获得;)
key (收款商户后台进行配置,登录微信商户平台–账户中心–API安全-设置秘钥,设置32位key值;)
mch_id (收款商家商户号;)
certPath (API证书, 登录微信商户平台–账户中心-API安全-下载证书)
后端流程
服务端需要的核心操作, 总共分为以下几步:
统一下单
前端调起微信支付必要参数 (需加密)
订单结果主动通知 (回调接口)
查询订单结果
结束订单支付接口(关闭订单,支付订单关闭)
代码
微信总共支持多种语言的sdk, 在官网可以下载例子, java程序也可以引入微信支付的sdk包, 但是github上的sdk已经很久没有更新了, 最好的选择, 也是我的选择, 在官网上下载sdk项目, 将其中所有java类copy到自己的项目中.
官网sdk下载目录
链接: 商户平台首页
#### 根据微信sdk生成配置类 WXPayConfig
创建IWxPayConfig.class, 继承sdk WXPayConfig.class, 实现sdk中部分抽象方法, 读取本地证书, 加载到配置类中.
package core.com.chidori.wxpay;
import core.com.wxpay.IWXPayDomain;
import core.com.wxpay.WXPayConfig;
import core.com.wxpay.WXPayConstants;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
@Service
public class IWxPayConfig extends WXPayConfig { // 继承sdk WXPayConfig 实现sdk中部分抽象方法
private byte[] certData;
@Value("${vendor.wx.config.app_id}")
private String app_id;
@Value("${vendor.wx.pay.key}")
private String wx_pay_key;
@Value("${vendor.wx.pay.mch_id}")
private String wx_pay_mch_id;
public IWxPayConfig() throws Exception { // 构造方法读取证书, 通过getCertStream 可以使sdk获取到证书
String certPath = "/data/config/chidori/apiclient_cert.p12";
File file = new File(certPath);
InputStream certStream = new FileInputStream(file);
this.certData = new byte[(int) file.length()];
certStream.read(this.certData);
certStream.close();
}
@Override
public String getAppID() {
return app_id;
}
@Override
public String getMchID() {
return wx_pay_mch_id;
}
@Override
public String getKey() {
return wx_pay_key;
}
@Override
public InputStream getCertStream() {
return new ByteArrayInputStream(this.certData);
}
@Override
public IWXPayDomain getWXPayDomain() { // 这个方法需要这样实现, 否则无法正常初始化WXPay
IWXPayDomain iwxPayDomain = new IWXPayDomain() {
@Override
public void report(String domain, long elapsedTimeMillis, Exception ex) {
}
@Override
public DomainInfo getDomain(WXPayConfig config) {
return new IWXPayDomain.DomainInfo(WXPayConstants.DOMAIN_API, true);
}
};
return iwxPayDomain;
}
}
发起统一下单 AND 前端调起微信支付必要参数
// 发起微信支付
WXPay wxpay = null;
Map result = new HashMap();
try {
// ******************************************
//
// 统一下单
//
// ******************************************
wxpay = new WXPay(iWxPayConfig); // *** 注入自己实现的微信配置类, 创建WXPay核心类, WXPay 包括统一下单接口
Map data = new HashMap ();
data.put("body", "订单详情");
data.put("out_trade_no", transOrder.getGlobalOrderId()); // 订单唯一编号, 不允许重复
data.put("total_fee", String.valueOf(transOrder.getOrderAmount().multiply(new BigDecimal(100)).intValue())); // 订单金额, 单位分
data.put("spbill_create_ip", "192.168.31.166"); // 下单ip
data.put("openid", openId); // 微信公众号统一标示openid
data.put("notify_url", ""); // 订单结果通知, 微信主动回调此接口
data.put("trade_type", "JSAPI"); // 固定填写
logger.info("发起微信支付下单接口, request={}", data);
Map response = wxpay.unifiedOrder(data); // 微信sdk集成方法, 统一下单接口unifiedOrder, 此处请求 MD5加密 加密方式
logger.info("微信支付下单成功, 返回值 response={}", response);
String returnCode = response.get("return_code");
if (!SUCCESS.equals(returnCode)) {
return null;
}
String resultCode = response.get("result_code");
if (!SUCCESS.equals(resultCode)) {
return null;
}
String prepay_id = response.get("prepay_id");
if (prepay_id == null) {
return null;
}
// ******************************************
//
// 前端调起微信支付必要参数
//
// ******************************************
String packages = "prepay_id=" + prepay_id;
Map wxPayMap = new HashMap ();
wxPayMap.put("appId", iWxPayConfig.getAppID());
wxPayMap.put("timeStamp", String.valueOf(Utility.getCurrentTimeStamp()));
wxPayMap.put("nonceStr", Utility.generateUUID());
wxPayMap.put("package", packages);
wxPayMap.put("signType", "MD5");
// 加密串中包括 appId timeStamp nonceStr package signType 5个参数, 通过sdk WXPayUtil类加密, 注意, 此处使用 MD5加密 方式
String sign = WXPayUtil.generateSignature(wxPayMap, iWxPayConfig.getKey());
// ******************************************
//
// 返回给前端调起微信支付的必要参数
//
// ******************************************
result.put("prepay_id", prepay_id);
result.put("sign", sign);
result.putAll(wxPayMap);
return result;
} catch (Exception e) {
}
回调结果处理
核心是支付订单回调时, 需校验加密签名是否匹配, 防止出现模拟成功通知
@RequestMapping(value = "/payCallback", method = RequestMethod.POST)
public String payCallback(HttpServletRequest request, HttpServletResponse response) {
logger.info("进入微信支付异步通知");
String resXml="";
try{
//
InputStream is = request.getInputStream();
//将InputStream转换成String
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + " ");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
resXml=sb.toString();
logger.info("微信支付异步通知请求包: {}", resXml);
return wxTicketService.payBack(resXml);
}catch (Exception e){
logger.error("微信支付回调通知失败",e);
String result = " ";
return result;
}
}
@Override
public String payBack(String notifyData) {
logger.info("payBack() start, notifyData={}", notifyData);
String xmlBack="";
Map notifyMap = null;
try {
WXPay wxpay = new WXPay(iWxPayConfig);
notifyMap = WXPayUtil.xmlToMap(notifyData); // 转换成map
if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
// 签名正确
// 进行处理。
// 注意特殊情况:订单已经退款,但收到了支付结果成功的通知,不应把商户侧订单状态从退款改成支付成功
String return_code = notifyMap.get("return_code");//状态
String out_trade_no = notifyMap.get("out_trade_no");//订单号
if (out_trade_no == null) {
logger.info("微信支付回调失败订单号: {}", notifyMap);
xmlBack = " ";
return xmlBack;
}
// 业务逻辑处理 ****************************
logger.info("微信支付回调成功订单号: {}", notifyMap);
xmlBack = " ";
return xmlBack;
} else {
logger.error("微信支付回调通知签名错误");
xmlBack = " ";
return xmlBack;
}
} catch (Exception e) {
logger.error("微信支付回调通知失败",e);
xmlBack = " ";
}
return xmlBack;
}
统一下单的签名和后续前端拉取微信支付的签名需要统一, 也就是都采用MD5加密, 如果2者不同, 会导致前端拉取微信支付fail, 这是一个巨大的坑, 因为这个原因调试了好久, 微信在文档里没有明确标出统一下单的签名校验方式 需要和前端拉取微信支付的签名校验保持一致.
微信sdk里的源码需要针对这个问题调整一下, 调整如下:
WXPay类需要修改下加密判断,在WXPay构造方法中,调整如下
public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport, final boolean useSandbox) throws Exception {
this.config = config;
this.notifyUrl = notifyUrl;
this.autoReport = autoReport;
this.useSandbox = useSandbox;
if (useSandbox) {
this.signType = SignType.MD5; // 沙箱环境
}
else {
this.signType = SignType.MD5; // 将这里的加密方式修改为SignType.MD5, 保持跟前端吊起微信加密方式保持一致
}
this.wxPayRequest = new WXPayRequest(config);
}
结束语
做完以后, 微信支付的后端逻辑还是很清晰的, 但是在开发过程中很煎熬, 不清楚每个专业术语在微信哪里配置, 加密方式乱的很
解决vue2.x中数据渲染以及vuex缓存的问题
最近在学习Vue.js,把自己遇到的问题做个记录,所以,今天添加一点小笔记。
在项目中遇到两个问题,简单的做个笔记来记录自己解决的问题,可能不是很好的处理办法,欢迎提出,自己还在不断优化中...
第一个是vue在加载页面的时候,会先加载静态资源,这个时候数据还没有请求回来,用户会先看到静态的内容(就是页面固定写死的),过一会才会有数据回来渲染,这体验是很差的,其实解决办法也很简单,就是用vue里的
v-if
来判断请求的数据是否返回...
div
class="container"
id="app"
v-cloak
div
v-if='moneyInMsg.uuid'
in-account-msg
:money-in-msg="moneyInMsg"/in-account-msg
/div
/div
这里的
v-if
=
'moneyInMsg.uuid'
就是来判断数据有没有请求回来,如果请求回来就让他显示,没有请求到数据,就让他loading,这样体验就会好很多。在这里还需要注意的是,v-if判断的数据源,是数据返回的字段,如果两个字段只能存在其一的话,可以v-if
='a
||
b'
来判断数据是否成功的返回;还要注意的一点是,不能直接在组件里用v-if判断,也不能直接在根标签里判断,直接嵌套一个div就可以解决,并不影响样式,只做数据是否正常返回的显示作用;
第二个就是在使用vuex时,有数据缓存;我遇到的情况是,在列表页点击进入详情页,返回到列表页,在进入另一个详情页的时候,数据会显示之前的数据,同时页面还在loading(接口返回的数据比较慢),过一会数据返回的时候,才重新渲染页面。可能是自己对vuex理解的不够深入,没有在vuex基础上解决这个问题。虽然曲折的解决了这个问题,但是不够zhuang,但是解决了问题,后期再做优化。
在之前解决的方案中,是进入页面的时候,重新刷新页面,重新请求数据,代码如下:
export
const
refresh
=
(title)
=
{
document.title
=
title;
let
iframe
=
document.createElement('iframe');
iframe.src
=
require('./mm.jpg');
iframe.setAttribute('style',
'display:none;');
let
loadFn
=
function
()
{
iframe.removeEventListener('load',
loadFn);
document.body.removeChild(iframe);
console.info('Page
Title
IS
'
+
title);
iframe
=
null;
loadFn
=
null;
}
document.body.appendChild(iframe)
iframe.addEventListener('load',
loadFn);
}
但是没有达到预期的效果,依然会出现上面的情况...
丫的,抓狂了...(被别人催的感觉真的不爽...)
百度啊,google啊,都没有遇到这种情况的?找到一个,还是提问的,没有回答的,好吧,还是靠自己。自己动手,丰衣足食啊...
思路是,定义一个参数status为false,当数据没有请求回来,就不显示,也是用上面的方式来判断,一直loading(请求失败,去掉loading),当数据返回的时候,让status为true;使用$nextTick来更新数据...
贴上自己部分的代码作为参考:
template
div
v-if='status
order.name'
//页面展示的数据
/div
/template
script
export
default{
data(){
return
{
status:false
}
},
created(){
var
_this
=
this;
this.setDd({res
={
_this.$nextTick(function(){
_this.status=
true
});
}})
},
computed:{
...mapGetters({//getter获取的数据})
},
methods:{
...mapActions(['setDd'])
//获取数据的方法
}
}
/script
处理的方式比较丑陋...,但是实现了想要的效果;这里注意一点就是v-if的判断问题。(v-if='status
order.name')这个用了并且,目的是有数据返回,才能让他显示,如果没有数据,会显示静态的值,数据都为underfind...
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。