说明:
都是写给自己和小姐妹看的东西,简单且繁琐,一堆废话。大佬就别点进来耽误时间了emm。
第一天(0803):
- 作业内容
创建新应用后邀请伙伴加入
- 备注
但是不知道是什么原因,我和我的小伙伴都无法复制出邀请链接,于是用创建子账号的方式添加了应用成员。
第二天(0804):
- 作业内容
安装node.js之后配置MidwayJs,使用f create创建一个标准函数,使用invoke返回helloworld和自己的名字。
- 备注
这作业乍一看有些复杂,因为我还没接触过f create这个命令。但好在钉钉群里给了教程,可以跟着做。(首先需要安装node.js,网上很多教程,我就不写了) - 实现过程
1. 安装MidwayJs
在终端(windows:对着左下角右键,管理员身份运行)使用npm i @midwayjs/faas-cli -g
命令安装MidwayJs,首先出现了第一个报错:
小知识:
--save相当于-s,
--global相当于-g,
--save-dev相当于-d,
--save-optional相当于-o,
--save-exact相当于-e。
容易看出,错误原因是没有这条命令的执行权限(因为在mac上好像没有管理员权限的命令行窗口,实现管理员权限靠的是命令前加上sudo,所以经常因为忘记加sudo而报错)。
忽略warn,似乎安装成功了。
2. f create新建项目
按照教程,下一步是“f create”->回车->项目名->回车,但我在f create后,终端会变成不可输入的状态。
无法输入用户名。然后我一顿瞎按,发现还需要再按一次回车emmm…第二次回车是选中蓝色的那行默认标准。所以流程是“f create”->回车->回车->项目名->回车->回车。
还有个小心心,还挺可爱。
3. 安装依赖
输入这两行代码:第一行:进入新建的项目目录,第二行:下载依赖(=npm install)。
4. invoke输出
最后,输入f invoke -f index
,得到hello world,完成。
5. 在输出中添加自己的名字
并没有完成,我没有返回我的名字。又换了个教程发现要在vs里面写(安装vs可以在网上找教程,有很多很好玩的插件可以设置,如果下载速度太慢的话就找一下镜像文件)。打开vs。
先在电脑里搜索刚刚新建的项目文件夹:helloworld-demo,
然后把这个文件夹拖入vs,成功打开。
有“node_modules”这个文件夹,说明已经安装好依赖了。
在这里加上自己的名字,之后在终端输入f invoke -f index
。如果没有终端的话cmd+shift+p(win的话应该是crl+alt+p?此处存疑),打开终端。
成功输出helloworld和名字,截图交作业。
第三天(0805):
继续写(chao)作业。
- 作业内容
在云开发平台根据技术场景模版创建“Midway Serverless
一体化解决方案”应用,通过浏览器访问函数接口,修改函数代码加上你的名字返回
- 备注
感觉自己好像会了一些东西。 - 实现过程
1. 云开发平台新建应用
打开阿里云主页https://cn.aliyun.com/->开发者->云开发平台
进入应用列表->新建应用->设置如图
自己填,然后完成就行了。
2. cloudIDE
点击开发部署,进入cloudIDE终端在这
在终端输入npm i
安装依赖。
安装完成,warn忽略。
找到index.ts文件,在message中添加上自己的名字。
然后在终端输入npm run dev
。
得到一个网址,点击打开这个网址,截图上交。
第四天(0806):
- 作业内容
在云开发平台使用“Koa应用迁移方案”模板创建一个Koa应用,使用koa-ejs进行服务端渲染,通过浏览器访问你开发的http接口,返回Hi Serverless加上你的名字截图即可
- 备注
感觉每天都在接触新词汇,慢慢来吧。
“知道的越多,越觉得自己什么都不知道,但是确实是知道的越来越多了。” - 实现过程
1.云开发平台新建应用
和第三天的1.是差不多的,只是具体的选项选的不一样,这里我们根据题目选择web-Koa应用迁移方案
2. cloudIDE
a.点击“开发部署”,进入cloudIDE
b.安装依赖
这一步在第三天的2.中有讲过。
在终端输入npm i
c.在app.js文件下面添加代码
router.get('/', (ctx, next) => {
ctx.body = '<h1>Hi Serverless 你的名字</h1> '
});
d.启动应用
在终端输入node app.js
,
然后左下角点击预览->端口号输入3000->访问
成功。
第五天(0807):
- 作业内容
在云开发平台使用实验室:WEB 解决方案:Midway Serverless OTS数据库示例模板创建Todo List应用,利用自己OTS数据库,添加一条自己名字的Todo并截图
- 备注
最后三次作业啦!冲冲冲~ - 实现过程
1. 云开发平台新建应用
设置如图
2.cloudIDE
a.进入IDE,安装依赖
在终端输入npm i
b.表格存储
进入阿里云OTS表格存储网站https://www.aliyun.com/product/ots,开通表格存储
进入控制台,创建实例
输入一个好记的实例名称,别的不用更改,确定即可。
进入实例管理,
得到公网ip。
点击创建数据表,
表名称为list,主键为id。
点击确定。
获取自己的accesskey ID和accesskey Secret,未创建的可以点击新建。
c.回到cloudIDE
找到文件“src/apis/configuration.ts“,
找到这端代码,
依次将信息改为自己的accesskey ID、accesskey Secret、公网ip、实例名称,记得要用 ’ ’ 扩起来。
crtl+s保存之后,在终端输入npm run dev
,得到一个网址,(com/crtl+单机)打开网址后,输入自己的名字并回车,截图交作业。
第六天(0810):
- 作业内容
在云开发平台使用 “Midway Serverless Mysql 数据库示例”创建一个函数应用,编写查询共有多少条数据的sql语句,执行函数返回数据数量,截图即可
- 备注
现在是8.12早上7:30,做噩梦惊醒之后突然意识到这个作业昨晚截止,不愧是我qwq但是有始有终叭,把记录给写完。 - 实现过程
1.云开发平台新建应用
实验室->web->Midway Serverless MySQL数据库示例
2.cloudIDE
a.安装依赖
npm i --registry=https://registry.npm.taobao.org
b.部署
在f.yml里编写入口文件
count:
handler: count.headler
events:
- apigw:
path: /api/count
在index.ts里面编写一个函数
@Func('count.handler')
async count() {
const result = await this.db.query(`select count(*) from todo`);
return result;
}
在终端输入npm run dev
,得到一个地址,在地址后添加/api/count后访问,得到结果。
第七天(0812):
- 作业内容
在云开发平台使用 MySQL 或者 OTS 模板创建应用,使用自己的对应数据库实现一个注册和登陆系统,提交2个截图,①注册成功后提示注册成功的截图,②使用注册的账号登录,展示信息的截图
- 备注
最后一天作业啦! - 实现过程
- 参考资料:云开发创造营 · 第七天课程资料
1.云开发平台新建应用
参考第五天内容,新建ots类型应用,创建表格存储,记得在configuration.ts里关联实例。
2. 后端
a.编写入口文件:
register:
handler: user.register
events:
- apigw:
path: /api/register
login:
handler: user.login
events:
- apigw:
path: /api/login
b.新建后端文件user.ts
import { Func, Inject, Provide } from '@midwayjs/decorator';
import TableStore from 'tablestore';
import format from 'otswhere/format';
@Provide()
export class TodoService {
@Inject()
ctx;
@Inject()
tb;
@Func('user.login')
async login() {
const { name, password } = this.ctx.query;
const params = {
tableName: 'user',
direction: TableStore.Direction.BACKWARD,
inclusiveStartPrimaryKey: [{ id: TableStore.INF_MAX }],
exclusiveEndPrimaryKey: [{ id: TableStore.INF_MIN }]
};
return new Promise(resolve => {
this.tb.getRange(params, (_, data) => {
const rows = format.rows(data, { email: true });
const userExists = rows.list.findIndex(user => user.name === name) !== -1
if (!userExists) {
resolve({
success: false,
message: '用户不存在'
})
return
}
const user = rows.list.find(user => user.name === name)
console.log(user.password, password)
if (user.password !== password) {
resolve({
success: false,
message: '密码错误'
})
return
}
resolve({
success: true,
user
});
});
})
}
@Func('user.register')
async register() {
const { name, password } = this.ctx.query;
const params = {
tableName: "user",
condition: new TableStore.Condition(TableStore.RowExistenceExpectation.IGNORE, null),
primaryKey: [
{ id: `${Date.now()}-${Math.random()}` }
],
attributeColumns: [
{ name },
{ password },
{ status: '1' }
]
};
return new Promise(resolve => {
this.tb.putRow(params, async function (err, data) {
if (err) {
resolve({
success: false,
errmsg: err.message
});
} else {
resolve({
success: true,
data
});
}
});
});
}
}
下面代码覆盖index.tsx
import React, { useEffect, useState } from 'react'
import ReactDOM from 'react-dom';
export default function App() {
const [name, setName] = useState('')
const [password, setPassword] = useState('')
const handleSubmit = () => {
console.log(name, password)
fetch(`/api/register?name=${name}&password=${password}`)
.then(resp => resp.json())
.then(resp => {
console.log(resp)
if (resp.success == true) {
alert('注册成功')
}
})
}
const handleLogin = () => {
fetch(`/api/login?name=${name}&password=${password}`)
.then(resp => resp.json())
.then(resp => {
if (resp.success == true) {
alert(`登录成功,提示信息:${resp.user.name}`)
} else {
alert(`登陆失败,提示信息:${resp.message}`)
}
})
}
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-md w-full">
<div>
<img className="mx-auto h-12 w-auto" src="https://tailwindui.com/img/logos/workflow-mark-on-white.svg" alt="Workflow" />
<h2 className="mt-6 text-center text-3xl leading-9 font-extrabold text-gray-900">
注册或者登录
</h2>
</div>
<form className="mt-8" action="#" method="POST">
<input type="hidden" name="remember" defaultValue="true" />
<div className="rounded-md shadow-sm">
<div>
<input
onChange={e => { setName(e.target.value) }}
//获取前端用户名
aria-label="Email address" name="email" type="email" required className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 sm:text-sm sm:leading-5" placeholder="Email address" />
</div>
<div className="-mt-px">
<input
onChange={e => { setPassword(e.target.value) }}
//获取前端密码
aria-label="Password" name="password" type="password" required className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 sm:text-sm sm:leading-5" placeholder="Password" />
</div>
</div>
<div className="mt-6">
<button type="button" onClick={handleSubmit} className="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm leading-5 font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo active:bg-indigo-700 transition duration-150 ease-in-out">
<span className="absolute left-0 inset-y-0 flex items-center pl-3">
</span>
注册
</button>
</div>
<div className="mt-6">
<button type="button" onClick={handleLogin} className="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm leading-5 font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo active:bg-indigo-700 transition duration-150 ease-in-out">
<span className="absolute left-0 inset-y-0 flex items-center pl-3">
</span>
登录
</button>
</div>
</form>
</div>
</div>
)}
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
3. 前端
下面代码覆盖public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Todo List</title>
<link href="https://cdn.bootcdn.net/ajax/libs/tailwindcss/1.6.2/tailwind.min.css" rel="stylesheet">
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
4.完成截图