添加请求响应工具类

注册模块对接服务端
master
pan 5 years ago
parent 4610001721
commit f28d8c283a
  1. 71
      src/account/Register.tsx
  2. 12
      src/entity.ts
  3. 92
      src/interface.ts
  4. 10
      src/my/MyInfo.tsx
  5. 2
      src/my/MyLeaveWord.tsx
  6. 26
      src/result.ts
  7. 6
      src/sub/SendHelp.tsx
  8. 2
      src/sub/Volunteer.tsx
  9. 1
      src/ui/TestData.ts
  10. 47
      src/ui/UploadImg.tsx

@ -1,9 +1,12 @@
import React, {RefObject} from "react"; import React from "react";
import {Input} from "../ui/InputGroup"; import {Input} from "../ui/InputGroup";
import {Button, Form} from 'react-bootstrap' import {Button, Form} from 'react-bootstrap'
import {RegisterProps, RegisterState, UserType} from "../entity"; import {RegisterProps, RegisterState, UserType} from "../entity";
import {UploadImg} from "../ui/UploadImg"; import {UploadImg} from "../ui/UploadImg";
import {Address} from "../ui/Address"; import {Address} from "../ui/Address";
import {API, JSONResponse, Method, request} from "../interface"
import {RegisterMessage, RegisterTransform} from "../result";
import {MyDialog} from "../ui/MyDialog";
/** /**
* *
@ -13,23 +16,20 @@ const maxImageSize={
height:100 height:100
} }
const headimgTip="请上传头像"
/** /**
* *
*/ */
export class Register extends React.Component<RegisterProps, RegisterState>{ export class Register extends React.Component<RegisterProps, RegisterState>{
//存放头像
private fileImg: RefObject<any>;
constructor(props: Readonly<RegisterProps>) { constructor(props: Readonly<RegisterProps>) {
super(props) super(props)
this.state={ this.state={
result: null,
sex: "", sex: "",
address: "", address:"",
serviceAddress: "",
age: 0, age: 0,
email: "", email: "",
headImg: headimgTip,
info: "", info: "",
mobile: 0, mobile: 0,
name: "", name: "",
@ -39,13 +39,46 @@ export class Register extends React.Component<RegisterProps, RegisterState>{
userType:"" userType:""
} }
this.fileImg=React.createRef()
} }
//注册 //注册
register(){ register(){
console.debug(this.state); let that=this
request(API.account.register,Method.PUT, {
userId:this.state.userId,
password:this.state.password,
name:this.state.name,
sex:this.state.sex,
imgFile:this.state.imgFile,
address:this.state.address,
serviceAddress:this.state.serviceAddress,
userType:this.state.userType,
mobile:String(this.state.mobile),
email:this.state.email,
info:this.state.info
},function () {
return new RegisterTransform()
},function(res:JSONResponse<RegisterMessage>){
let message
switch (res.customResult) {
case RegisterMessage.ok:message="注册成功";
that.setState({
result:<div className="text-center"><Button variant="info" onClick={()=>that.props.toLogin()}></Button></div>
})
break
case RegisterMessage.fail:message="注册失败,请联系管理员";
// eslint-disable-next-line no-fallthrough
case RegisterMessage.form_parse_error:message="表单不合法,请联系管理员"
// eslint-disable-next-line no-fallthrough
case RegisterMessage.user_repeat:message="用户id'"+that.state.userId+"'重复,请更换"
that.setState({
result:<h3 className="text-danger text-center">{message}</h3>
})
break
}
})
} }
//检查是否为空 //检查是否为空
@ -65,8 +98,8 @@ export class Register extends React.Component<RegisterProps, RegisterState>{
//检查表单 //检查表单
check(){ check(){
return this.isNotEmpty(this.state.userId,this.state.password,this.state.name,this.state.sex,this.state.address,this.state.userType,this.state.info) return this.isNotEmpty(this.state.userId,this.state.password,this.state.name,this.state.sex,this.state.serviceAddress,this.state.userType,this.state.info)
&&this.state.headImg!==headimgTip&&this.checkPwd()&&this.checkMobile()&&this.checkEmail() &&this.state.imgFile!=null&&this.checkPwd()&&this.checkMobile()&&this.checkEmail()
} }
/** /**
@ -83,6 +116,8 @@ export class Register extends React.Component<RegisterProps, RegisterState>{
return /[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}/g.test(this.state.email) return /[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}/g.test(this.state.email)
} }
render() { render() {
return ( return (
<div className="d-flex align-items-center" style={{height:window.screen.availHeight+'px'}}> <div className="d-flex align-items-center" style={{height:window.screen.availHeight+'px'}}>
@ -104,9 +139,14 @@ export class Register extends React.Component<RegisterProps, RegisterState>{
<Input col={4} name="sex" desc="性别" as="select" onChange={(value:string)=>this.setState({sex:value})} <Input col={4} name="sex" desc="性别" as="select" onChange={(value:string)=>this.setState({sex:value})}
options={[<option value="" key={"sex"+0}></option>,<option value="man" key={"sex"+1}></option>,<option value="women" key={"sex"+2}></option>]}/> options={[<option value="" key={"sex"+0}></option>,<option value="man" key={"sex"+1}></option>,<option value="women" key={"sex"+2}></option>]}/>
<UploadImg fileImg={this.fileImg} maxImageSize={maxImageSize} onChange={(value:string)=>this.setState({headImg:value})} imageName={this.state.headImg}/> <UploadImg maxImageSize={maxImageSize} onChange={(imgObj:any)=>
{
this.setState({imgFile:imgObj})
}} tip={"请上传头像"} />
<Input name="address" desc="住址" onChange={(value:string)=>this.setState({address:value})}/>
<Address onChange={(value:string)=>this.setState({address:value})}/> <Address onChange={(value:string)=>this.setState({serviceAddress:value})}/>
<Input col={4} name="userType" desc="用户身份" as="select" onChange={(value:string)=>this.setState({userType:value})} <Input col={4} name="userType" desc="用户身份" as="select" onChange={(value:string)=>this.setState({userType:value})}
options={[<option value="" key={"userType0"}></option>,<option key={"userType1"} value={UserType.help}></option>,<option key={"userType2"} value={UserType.seekHelp}></option>]}/> options={[<option value="" key={"userType0"}></option>,<option key={"userType1"} value={UserType.help}></option>,<option key={"userType2"} value={UserType.seekHelp}></option>]}/>
@ -115,6 +155,7 @@ export class Register extends React.Component<RegisterProps, RegisterState>{
<Input col={4} name="email" desc="邮箱" onChange={(value:string)=>this.setState({email:value})} valid={{check:this.checkEmail()}}/> <Input col={4} name="email" desc="邮箱" onChange={(value:string)=>this.setState({email:value})} valid={{check:this.checkEmail()}}/>
{/*TODO 简介长度要限制*/}
<Input col={7} name="info" desc="简介" as={"textarea"} onChange={(value:string)=>this.setState({info:value})} valid={{check:this.isNotEmpty(this.state.info)}}/> <Input col={7} name="info" desc="简介" as={"textarea"} onChange={(value:string)=>this.setState({info:value})} valid={{check:this.isNotEmpty(this.state.info)}}/>
<Button variant="success" className="mt-3 col-2 mr-3" disabled={!this.check()} onClick={()=>this.register()}></Button> <Button variant="success" className="mt-3 col-2 mr-3" disabled={!this.check()} onClick={()=>this.register()}></Button>
@ -122,6 +163,8 @@ export class Register extends React.Component<RegisterProps, RegisterState>{
<Button variant="info" className="mt-3 col-2" onClick={()=>this.props.toLogin()}></Button> <Button variant="info" className="mt-3 col-2" onClick={()=>this.props.toLogin()}></Button>
</Form> </Form>
</div> </div>
<MyDialog content={this.state.result} open={this.state.result!==null} titleId="register-tip" menuName="注册反馈" onClose={()=>this.setState({result:null})}/>
</div> </div>
); );
} }

@ -110,8 +110,6 @@ export interface SendHelpState extends BaseHelp{
address:string; address:string;
//推荐方式 //推荐方式
recommendType:RecommendType; recommendType:RecommendType;
//推荐目标
recommendTarget?:Array<number>;
//好友列表 //好友列表
friendList:Array<User>; friendList:Array<User>;
//已选中好友列表 //已选中好友列表
@ -185,12 +183,14 @@ export interface User{
mobile:number; mobile:number;
//用户邮箱 //用户邮箱
email:string; email:string;
//地点 //住址
address:string; address:string;
//服务地点
serviceAddress:string;
//个人简介 //个人简介
info:string; info:string;
//头像 //头像
headImg:string; headImg?:string;
//性别 //性别
sex:string; sex:string;
//身份 //身份
@ -271,6 +271,10 @@ export interface RegisterState extends User{
password: string; password: string;
//确认密码 //确认密码
confirmPwd:string; confirmPwd:string;
//用户头像
imgFile?:any;
//注册结果
result:JSX.Element|null;
} }
/** /**

@ -0,0 +1,92 @@
//服务端地址
const server="http://localhost:8080"
const prefix={
user:"/api/user"
}
//服务器接口地址
export const API={
account:{
register:prefix.user+"/register"
}
}
export enum Method {
PUT="PUT",
POST="POST",
GET="GET"
}
export enum Result {
OK,
FAIL
}
/**
*
*/
export abstract class JSONResponse<Q> {
result?:Result
customResult?:Q
}
/**
*
*/
export abstract class TransformData<Q,T extends JSONResponse<Q>> {
protected target: T
constructor() {
this.target = this.newObject();
}
protected abstract newObject(): T
public transform(data:any){
this.transformResult(data)
this.transformBody(data)
return this.target
}
protected transformBody(data:any){
}
private transformResult(data:any){
if("result" in data ) {
this.target.result = data.result
}
if("customResult" in data){
this.target.customResult = data.customResult
}
}
}
//发送请求
export function request<Q,E extends JSONResponse<Q>,T extends TransformData<Q,E>>(api:string,method:Method,formParams: {[propName:string]: string | Blob},transformFun:Function,callback:Function) {
let formData=new FormData()
for(let formParam in formParams){
formData.append(formParam,formParams[formParam])
}
fetch(server+api,{
method:Method.PUT,
body:formData
})
.then(
response=>{if(response.status===200){
return response.json()
}else{
throw new Error("遇到无法处理的错误,请联系管理员")
}}
)
.catch(
error =>console.error('Error:', error)
)
.then((response:JSONResponse<Q>)=>{
let transform:T=transformFun()
callback(transform.transform(response))
})
}

@ -34,8 +34,9 @@ export class MyInfo extends React.Component<
mobile:0, mobile:0,
//用户邮箱 //用户邮箱
email:"", email:"",
//地点
address:"", address:"",
//地点
serviceAddress:"",
//个人简介 //个人简介
info:"", info:"",
//性别 //性别
@ -61,7 +62,7 @@ export class MyInfo extends React.Component<
age:Math.ceil(Math.random()*100)+1, age:Math.ceil(Math.random()*100)+1,
mobile:1234567879, mobile:1234567879,
email:"admin@qq.com", email:"admin@qq.com",
address:"上海高新区", serviceAddress:"上海高新区",
info:"个人简介", info:"个人简介",
userType:UserType.help.toString() userType:UserType.help.toString()
}) })
@ -137,6 +138,7 @@ export class MyInfo extends React.Component<
<Image className="chat-headImg" src={this.state.headImg}/> <Image className="chat-headImg" src={this.state.headImg}/>
</Col> </Col>
</Row> </Row>
{/*TODO 表单校验*/}
<Row> <Row>
<Col className="border-info border p-3 text-center">{this.state.userId}</Col> <Col className="border-info border p-3 text-center">{this.state.userId}</Col>
<Col className="border-info border p-3 text-center"> <Col className="border-info border p-3 text-center">
@ -171,8 +173,8 @@ export class MyInfo extends React.Component<
<Row> <Row>
<Col className="border-info border p-3 text-center"> <Col className="border-info border p-3 text-center">
{this.state.contentEditable? {this.state.contentEditable?
<FormControl value={this.state.address} onChange={(e)=>this.setState({address:e.target.value})}/> <FormControl value={this.state.serviceAddress} onChange={(e)=>this.setState({serviceAddress:e.target.value})}/>
:this.state.address} :this.state.serviceAddress}
</Col> </Col>
</Row> </Row>
<Row> <Row>

@ -178,6 +178,6 @@ export class MyLeaveWord extends React.Component<{ user:string },
open={this.state.openActivity} titleId="view-activity" menuName="活动详情" open={this.state.openActivity} titleId="view-activity" menuName="活动详情"
onClose={()=>this.setState({activity:undefined,openActivity:false})}/>:null} onClose={()=>this.setState({activity:undefined,openActivity:false})}/>:null}
</div> </div>
); )
} }
} }

@ -0,0 +1,26 @@
/**
*
*/
import {JSONResponse, TransformData} from "./interface";
export enum RegisterMessage {
//注册成功
ok = "ok",
//系统异常,注册失败
fail = "fail",
//用户id重复
user_repeat = "user_repeat",
//表单解析错误
form_parse_error = "form_parse_error"
}
class RegisterRes implements JSONResponse<RegisterMessage> {
}
export class RegisterTransform extends TransformData<RegisterMessage, RegisterRes> {
protected newObject(): RegisterRes {
return new RegisterRes();
}
}

@ -30,8 +30,6 @@ const recommendType=[RecommendType.no, RecommendType.choose,RecommendType.auto]
* *
*/ */
export class SendHelp extends React.Component<{ undefined?:undefined }, SendHelpState>{ export class SendHelp extends React.Component<{ undefined?:undefined }, SendHelpState>{
//存放活动背景图
private fileImg: RefObject<any>;
//当前选中的好友索引 //当前选中的好友索引
private friendIndex:RefObject<any>; private friendIndex:RefObject<any>;
@ -53,8 +51,6 @@ export class SendHelp extends React.Component<{ undefined?:undefined }, SendHelp
chooseFriendList: {} chooseFriendList: {}
} }
this.fileImg=React.createRef()
this.friendIndex=React.createRef() this.friendIndex=React.createRef()
} }
@ -120,7 +116,7 @@ export class SendHelp extends React.Component<{ undefined?:undefined }, SendHelp
}} dateFormat="YYYY-MM-DD" timeFormat="HH:mm:ss"/> }} dateFormat="YYYY-MM-DD" timeFormat="HH:mm:ss"/>
</InputGroup> </InputGroup>
<UploadImg fileImg={this.fileImg} maxImageSize={maxImageSize} onChange={(value:string)=>this.setState({activityImg:value})} imageName={this.state.activityImg}/> <UploadImg tip={"请上传活动背景图"} maxImageSize={maxImageSize} onChange={(value:string)=>this.setState({activityImg:value})} />
{/*服务地点*/} {/*服务地点*/}
<Address onChange={(value:string)=>this.setState({address:value})}/> <Address onChange={(value:string)=>this.setState({address:value})}/>

@ -99,7 +99,7 @@ export class Volunteer extends React.Component<{ undefined?:undefined }, {
<div > <div >
<Table> <Table>
<tbody> <tbody>
{[[volunteer.name,volunteer.sex,volunteer.age],[volunteer.mobile,volunteer.email,volunteer.address]].map((tr,index)=> {[[volunteer.name,volunteer.sex,volunteer.age],[volunteer.mobile,volunteer.email,volunteer.serviceAddress]].map((tr, index)=>
<tr key={"tr"+index}> <tr key={"tr"+index}>
{tr.map((td,index)=><td key={"td"+index} className="border border-info">{td}</td>)} {tr.map((td,index)=><td key={"td"+index} className="border border-info">{td}</td>)}
</tr> </tr>

@ -14,6 +14,7 @@ export const userObj={
mobile:1234567879, mobile:1234567879,
email:"admin@qq.com", email:"admin@qq.com",
address:"上海高新区", address:"上海高新区",
serviceAddress:"上海",
info:"个人简介", info:"个人简介",
//性别 //性别
sex:"男", sex:"男",

@ -1,4 +1,4 @@
import React, {RefObject} from "react"; import React from "react";
import {Form, Image} from "react-bootstrap"; import {Form, Image} from "react-bootstrap";
import path from "path"; import path from "path";
@ -7,8 +7,8 @@ import path from "path";
*/ */
export class UploadImg extends React.Component< export class UploadImg extends React.Component<
{ {
//文件对象 //tip
fileImg:RefObject<any>; tip:string,
//图片尺寸限制 //图片尺寸限制
maxImageSize:{ maxImageSize:{
width:number, width:number,
@ -16,17 +16,18 @@ export class UploadImg extends React.Component<
}; };
//上传事件 //上传事件
onChange:Function; onChange:Function;
//图片文件名 }, {
imageName:string; //imgObj
}, any>{ imgObj?:any;
//图片文件名
imageName?:string;
}>{
/**
* url constructor(props: Readonly<{ tip: string; maxImageSize: { width: number; height: number }; onChange: Function }>) {
*/ super(props);
getUrl(){
if(this.props.fileImg.current!==null&&this.props.fileImg.current.files.length>0) { this.state={}
return URL.createObjectURL(this.props.fileImg.current.files[0])
}
} }
render() { render() {
@ -35,11 +36,11 @@ export class UploadImg extends React.Component<
{/* {/*
*/} */}
<Image className="mt-3 d-none" src={this.getUrl()} onLoad={(s)=> { <Image className="mt-3 d-none" src={this.state.imgObj} onLoad={(s)=> {
if(s.target instanceof HTMLImageElement){ if (s.target instanceof HTMLImageElement) {
//限制图片显示大小 //限制图片显示大小
s.target.width=s.target.width>this.props.maxImageSize.width?this.props.maxImageSize.width:s.target.width s.target.width = s.target.width > this.props.maxImageSize.width ? this.props.maxImageSize.width : s.target.width
s.target.height=s.target.height>this.props.maxImageSize.height?this.props.maxImageSize.height:s.target.height s.target.height = s.target.height > this.props.maxImageSize.height ? this.props.maxImageSize.height : s.target.height
s.target.classList.remove('d-none') s.target.classList.remove('d-none')
} }
} }
@ -48,11 +49,17 @@ export class UploadImg extends React.Component<
{/*上传背景图*/} {/*上传背景图*/}
<div className="col-7 ml-auto mr-auto mt-3"> <div className="col-7 ml-auto mr-auto mt-3">
<Form.File <Form.File
ref={this.props.fileImg} label={this.state.imageName?path.basename(this.state.imageName.replace(/\\/g,'/')):this.props.tip}
label={path.basename(this.props.imageName.replace(/\\/g,'/'))}
custom custom
accept="image/*" accept="image/*"
onChange={(e:any)=>this.props.onChange(e.target.value)} onChange={(e:any)=>{
const file=e.target.files[0]
this.setState({
imgObj:URL.createObjectURL(file),
imageName:e.target.value
})
this.props.onChange(file)
}}
/> />
</div> </div>
</div> </div>

Loading…
Cancel
Save