从零开始搭建SpringBoot项目(一)——开发环境搭建
从零开始搭建SpringBoot项目(二)——Swagger接口测试平台搭建
目录
| 需要安装 | 下载方法 |
|---|---|
| HbuilderX | 自备最新版本 |
| 微信开发者工具 | 官网下载链接 |
| 本章静态资源素材 | 百度网盘下载链接,提取码:edvr |
之前两篇文章我已经把后端的基础搭建好了,为了让大家能对项目开发有更直观的感受,这次我们先从小程序前端搭建入手,通过前端的设计我们自然就能知道向后端Java项目发出什么请求,提交什么数据了,以及后端系统要查询哪些表的记录才能客户端的需求。
本篇前半部分我会详细介绍Uni-app框架以及通过几个demo让大家了解小程序前端是如何运作的,有基础的同学可以直接跳到后面看实战代码。
我们本篇将要实现小程序的登录注册页面的如下👇

如何申请微信开发者账号就不介绍了,大家自行百度吧。
开发微信小程序必须要用到 AppID 和 密钥 ,这两个东西可以在微信开发者平台上面获得。在网页中找到开发栏目,然后选择开发设置选项卡,在面板中你就能看到自己的小程序对应的 AppID 和 密钥 了。如果是刚注册下来的账号,密钥还没有生成,你要手动点击页面上的按钮,生成密钥字符串。如果已经生成过密钥字符串,那么默认情况,页面会隐藏密钥字符串,你只能点击重置按钮,生成新的密钥字符串了。所以强烈建议大家,获取了密钥字符串之后,最好能用文件把密钥字符串保存下来。

大家打开HbuilderX工具,创建一个UNI-App项目👇


在左边项目栏打开刚刚创建的UNI-App项目,接着打开manifest.json文件,在里面找到微信小程序配置页面填下你自己的小程序AppID👇


然后选择运行微信小程序,之后将会自动启动微信开发者工具,并且让你扫码登陆

开发过微信小程序的人都应该知道,微信提供的开发语言十分不方便,而且开发页面显得繁杂,更重的是你就算学会了微信开发语言你还没办法应用在别的地方,而uni-app是一个基于VUE语法的跨平台移动端框架,会VUE的人,半天时间就能上手掌握uni-app框架。从项目结构,到页面语法,与前端的VUE工程几乎相同,我们何苦不学一门更大众化的语言呢?

uni-app 框架最让人着迷的地方在于,借助于 HBuilderX 工具,我们可以把 uni-app 项目,编译成各种类型的移动端工程。比如说我们可以把 uni-app 项目编译成微信小程序。

| 结构 | 用途 |
|---|---|
| pages目录 | 存放页面文件 |
| static目录 | 存放静态文件(图片) |
| App.vue文件 | 所有小程序页面都被引用到该文件运行 |
| main.js文件 | 项目入口文件,用来初始化VUE对象,定义全局组件等 |
| manifest.json文件 | 工程配置文件,声明应用的名称、图标、权限等 |
| pages.json文件 | 页面注册文件,配置页面路径、窗口样式、标题文字等 |
| uni.scss文件 | 全局样式文件 |


代码如下👇
"pages": [
{
"path": "pages/demo/demo",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
}
]
<template>
<view>
<view>{{username}}</view>
<view v-for="one in tel">{{one}}</view>
<view v-if="age>=18">
<button @tap="signUp">我要报名</button>
</view>
<view>
<input type="text" v-model="address" placeholder="输入地址" />
</view>
<view>输入的内容:{{address}}</view>
</view>
</template>
<script>
export default {
data() {
return {
username: "Scott",
tel: [13312345678, 15912345678],
age: 18,
address: ""
};
},
methods:{
signUp: function() {
uni.showToast({
title: "点击了报名按钮"
})
}
}
}
</script>
<style>
</style>
因为低版本的调试基础库对uni-app支持的不够好,所以我们要先把基础库的版本设置为最新,然后再运行小程序项目,不然报基础库版本低的错误。

刚刚demo.vue文件编译运行后👇

具体我们实现的页面效果呢,在文章开头已经向大家展示了。
大家看过效果应该发现这个登录和注册页面稍微有点不太一样,注册和登录页面是融合在一起。所以我们就不需要分别创建登录和注册文件了。
我们先来把静态的登陆注册页面和部分JS代码给设计出来。
大家在文章开头找到图片素材的百度网盘链接进行下载,然后把里面的static文件夹和colorui拷贝到当前小程序项目中,这样就成功导入登录注册所要的各种静态资源了。
①在小程序中创建login.vue文件👇

②然后在 page.json 文件中把这个文件的注册顺序设置成第一位👇

代码👇(千万别忘了用逗号分隔每个注册页面)
{
"path": "pages/login/login",
"style": {
"navigationBarTitleText": "欢迎来到何壹时的博客",
"enablePullDownRefresh": false
}
},
③创建 style.less 文件作为全局样式文件

@font-color: #333;
@desc-color: #999;
@background-color: #CC6633;
@background-color-active: #CC3333;
然后在 App.vue 文件中添加 css 公共样式👇

<style>
/*每个页面公共css */
@import "colorui/main.css";
@import "colorui/icon.css";
</style>
④编写 login.vue 文件👇
<template>
<view>
<view class="top-right-corner"></view>
<view class="lower-left-corner"></view>
<scroll-view scroll-y class="page">
<view class="container">
<view class="box login" :style="{'transform':login_page}">
<view class="form-content">
<view class="avtar">
<view class="pic">
<image src="/static/logo-1.png" alt="">
</view>
</view>
<view class="logo-title">登录注册页面</view>
<view class="cu-form-group">
<view class="padding flex flex-direction">
<button class="login-btn" open-type="getUserInfo" @tap="login()" >登陆</button>
</view>
</view>
<view class="btn-bottom">
还没有账户? <text @click="toSign()" class="signupbtn">注册</text>
</view>
</view>
</view>
<view class="box signup" :style="{'transform':signup_page}">
<view class="form-content">
<view class="avtar">
<view class="pic">
<image src="/static/logo-2.png" alt="">
</view>
</view>
<view>
<view class="padding flex flex-direction">
<button class="signup-btn" open-type="getUserInfo" @tap="register()">执行注册</button>
</view>
</view>
<view class="btn-bottom ">
已经有账号了? <text @click='tologin()' class="loginbtn">登陆</text>
</view>
</view>
</view>
</view>
<view class="cu-tabbar-height"></view>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
registerCode: '',
code:null,
login_page: '',
signup_page: ''
};
},
methods: {
toSign() { //跳转至注册页面
this.login_page = 'rotateY(180deg)';
this.signup_page = 'rotateY(0deg)';
},
tologin() { //跳转至登录页面
this.login_page = 'rotateY(0deg)';
this.signup_page = 'rotateY(-180deg)';
}
}
};
</script>
<style lang="scss">;
.page {
height: 100vh;
}
.top-right-corner {
position: fixed;
top: -280rpx;
right: -280rpx;
width: 600rpx;
height: 550rpx;
background-color: #FFFFFF;
border: 100rpx solid #ffdddf;
border-radius: 100%;
z-index: 1;
}
.lower-left-corner {
position: fixed;
bottom: -450rpx;
left: -200rpx;
width: 700rpx;
height: 680rpx;
background-color: #FFFFFF;
border: 100rpx solid #c7e1fa;
transform: rotate(-45deg);
z-index: 1;
}
.logo-title{
position: absolute;
font-size: 40upx;
font-weight: bold;
text-align: center;
margin-top: 5%;
}
.btn-box {
margin-top: 50rpx;
display: flex;
justify-content: center;
align-items: center;
height: 100rpx;
background-color: #496df4;
border-radius: 40rpx;
color: #FFFFFF;
font-size: 30rpx;
box-shadow: 0rpx 20rpx 40rpx #859df4;
}
.login-btn{
width: 60%;
position: absolute;
left: 20%;
background-color: #CC6633;
color: #fff;
box-sizing: border-box;
background-color: #496df4;
border-radius: 40rpx;
box-shadow: 0rpx 20rpx 40rpx #859df4;
&:active{
background-color: #859df4;
}
}
.signup-btn{
width: 60%;
position: absolute;
left: 20%;
color: #fff;
background-color: #496df4;
border-radius: 40rpx;
box-shadow: 0rpx 20rpx 40rpx #859df4;
box-sizing: border-box;
&:active{
background-color: #859df4;
}
}
.btn-bottom{
position: relative;
height: 20upx;
width: 100%;
text-align: center;
}
.container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 20rem;
height: 34rem;
perspective: 1500px;
-webkit-perspective: 1500px;
-moz-perspective: 1500px;
}
.box {
position: absolute;
top: 0;
left: 0;
width: 20rem;
height: 30rem;
border-radius: 10px;
cursor: pointer;
backface-visibility: hidden;
transition: all 0.5s;
user-select: none;
}
.signup {
transform: rotateY(-180deg); //解決切换闪烁问题
}
.container .form-content {
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
box-shadow: 0 0 1upx #3399ff;
border-radius: 30upx;
background-color: #fff;
}
.container .form-content .avtar {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
}
.container .form-content .avtar .pic {
position: relative;
width: 450upx;
height: 300upx;
overflow: hidden;
}
.container .form-content .avtar .pic image {
position: absolute;
width: 100%;
height: 100%;
}
.register-code{
border: 1upx solid #e0e0e0;
font-size: 34upx;
color: #333;
text-align: center;
background-color: #f5f5f5;
border-radius: 10upx;
margin-bottom: 30upx;
height: 80upx;
padding: 0 10upx;
margin-left: 20%;
margin-right: 20%;
}
.register-desc{
width: 70%;
margin-left: auto;
margin-right: auto;
color: #999;
font-size: 28rpx;
line-height: 1.5;
}
.loginbtn,
.signupbtn {
color: #0081ff;
}
</style>
首先我们可以从微信APP上面获得用户临时授权字符串(Code),然后把这个字符串传递给后端Java系统,让Java系统拿着AppId、密钥和Code,提交给微信平台换取OpenId👇
String url = "https://api.weixin.qq.com/sns/jscode2session";
HashMap map = new HashMap();
map.put("appid", appId);
map.put("secret", appSecret);
map.put("js_code", code);
map.put("grant_type", "authorization_code");
String response = HttpUtil.post(url, map);
JSONObject json = JSONUtil.parseObj(response);
String openId = json.getStr("openid");
在 uni-app 框架中,包含了原生微信小程序的 wx 对象,我们可以像写原生微信小程序代码一样,通过 wx 对象调用各种方法。但是我更推荐大家使用 uni 对象,因为这个对象是跨平台的,我们调用 uni 对象中的方法,HBuilderX 在编译代码的时候,会把 uni 对象翻译成目标平台的对象,比如微信平台就是 wx 对象,支付宝平台就是 my 对象,所以 uni 对象的跨平台性更好,而且调用更加简单,强烈推荐大家使用。
使用uni对象可以轻松获取微信小程序的临时授权字符串,这个临时授权字符串是有时间限定的,默认有效期是5分钟。如果过期,就无法换取 OpenId 了。


示例👇
uni.login({
provider: 'weixin',
success: function (resp) {
console.log(resp.code);
}
});

注意: 微信小程序端,在用户未授权过的情况下调用此接口,不会出现授权弹窗,会直接进入 fail 回调(详见《微信小程序公告》)。在用户已授权的情况下调用此接口,可成功获取用户信息。



示例1(该方法已经过时,微信小程序获取用户信息已经更新)
uni.login({
provider: 'weixin',
success: function (resp) {
let code = resp.code;
// 获取用户信息
uni.getUserInfo({
provider: 'weixin',
success: function (resp) {
let nickName = resp.userInfo.nickName;
let avatarUrl = resp.userInfo.avatarUrl;
}
});
}
});
示例2(推荐此种方式)
uni.login({
provider: 'weixin',
success: function (resp) {
let code = resp.code;
// 获取用户信息
uni.getUserProfile({
desc: '获取用户信息',
success: function (resp) {
let nickName = resp.userInfo.nickName;
let avatarUrl = resp.userInfo.avatarUrl;
}
});
}
});
注意此种获取用户信息的方式在真机调试上面可以使用,但是在小程序开发工具的微信模拟器上无法使用。所以大家运行用户注册的时候,必须用真机调试才行。

通过刚刚的了解,我们知道了uni-app提供了获取临时授权的方法,接下来我们就利用这个方法来编写我们的代码吧。
这里我会稍微有点超前的讲解,看不懂没关系,本来登录注册方法应该放在下一章和后端交互一起讲的,但想着刚刚介绍完获取临时授权和微信基本信息的方法那就趁热打铁吧!下一章将会详细讲解这部分代码的!
将以下这部分代码加到< script > < /script >的methods方法里吧👇
login: function() {
let that = this;
uni.login({
provider: 'weixin',
success: function(resp) {
let code = resp.code;
let token = uni.getStorageSync('token');
that.ajax(that.url.login, 'POST', { code: code }, function(resp) {
let permission = resp.data.permission;
uni.setStorageSync('permission', permission);
//跳转到登陆页面
uni.switchTab({
url: '../index/index'
});
});
},
fail: function(e) {
uni.showToast({
icon: 'none',
title: '执行异常'
});
}
});
},
register: function() {
let that = this;
uni.login({
provider: 'weixin',
success: function(resp) {
let code = resp.code;
that.code=code
}
});
uni.getUserProfile({
desc: '获取用户信息',
success: function(resp) {
let nickName = resp.userInfo.nickName;
let avatarUrl = resp.userInfo.avatarUrl;
// console.log(nickName);
// console.log(avatarUrl);
let data = {
code: that.code,
nickname: nickName,
photo: avatarUrl,
registerCode: that.registerCode
};
//下面这里封装了Ajax,下一章会讲解的
that.ajax(that.url.register, 'POST', data, function(resp) {
let permission = resp.data.permission;
let token = resp.data.token;
uni.setStorageSync('token', token);
uni.setStorageSync('permission', permission);
//跳转至主页
uni.switchTab({
url: '../index/index'
});
});
}
});
}
}

好了本次分享到此结束了!谢谢大家阅读!
下一章将会介绍小程序如何跟后端交互,以及如何将用户数据经过后端存储至MySQL!
之后会慢慢会恢复更新了,希望大家继续关注,还有更多优质博客在来的路上!!
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie
当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
我正在使用Postgres.app在OSX(10.8.3)上。我已经修改了我的PATH,以便应用程序的bin文件夹位于所有其他文件夹之前。Rammy:~phrogz$whichpg_config/Applications/Postgres.app/Contents/MacOS/bin/pg_config我已经安装了rvm并且可以毫无错误地安装pggem,但是当我需要它时我得到一个错误:Rammy:~phrogz$gem-v1.8.25Rammy:~phrogz$geminstallpgFetching:pg-0.15.1.gem(100%)Buildingnativeextension
在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主