【阿里云云开发】笔记(Midway OTS)-Day07

1.云开发平台创建一个应用


2.安装依赖

npm i --registry=https://registry.npm.taobao.org


3.开通ots数据库(前面笔记有写)

4.新增注册登录功能,编辑src/index.tsx

import React, { useState } from 'react'
import ReactDOM from 'react-dom';

export default function App() {
  const [name, setName] = useState('')
  const [password, setPassword] = useState('')

  const handleRegister = () => {
    console.log('name is', name)
    console.log('password is', password)

    fetch(`/api/register?name=${name}&password=${password}`)
    .then(resp => resp.json())
    .then(resp => {
      if (resp.success === true) {
        alert('注册成功')
      }
    })
  }

  const handleLogin = () => {
    console.log('name is', name)
    console.log('password is', password)

    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 => {
                  console.log('当前输入的账号是:', e.target.value)
                  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={handleRegister} 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')
);


5.创建新文件src/apis/user.ts
复制粘贴以下内容:

import { Func, Inject, Provide } from '@midwayjs/decorator';
import TableStore from 'tablestore';
import format from 'otswhere/format';

@Provide()
export class UserService {

  @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);
        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
          });
        }
      });
    });
  }
}


6.编辑:f.yml

  register:
    handler: user.register
    events:
      - apigw:
          path: /api/register
  login:
    handler: user.login
    events:
      - apigw:
          path: /api/login



7.清空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>

8.在OTS数据库里配置

数据表名称 - user
表主键 - id

访问尝试即可,不建议环境变量注入。

发表评论

路人甲 表情
看不清楚?点图切换 Ctrl+Enter快速提交

网友评论(0)

sitemap