1.修改用户信息增加性别,年龄等详细信息修改项

2.活动管理可修改活动标题,内容
0603
pan 5 years ago
parent bff2d70529
commit 233cb66ef2
  1. 3
      package.json
  2. 107
      src/Active.tsx
  3. 3
      src/Main.tsx
  4. 135
      src/User.tsx
  5. 6
      src/api.ts
  6. 15
      src/entity.ts
  7. 56
      src/ui/Address.tsx
  8. 8
      src/ui/MyDialog.tsx
  9. 5
      yarn.lock

@ -13,6 +13,7 @@
"@types/react-dom": "^16.9.0", "@types/react-dom": "^16.9.0",
"bootstrap": "^4.5.0", "bootstrap": "^4.5.0",
"http-proxy-middleware": "^1.0.4", "http-proxy-middleware": "^1.0.4",
"moment": "^2.26.0",
"react": "^16.13.1", "react": "^16.13.1",
"react-bootstrap": "^1.0.1", "react-bootstrap": "^1.0.1",
"react-cookie": "^4.0.3", "react-cookie": "^4.0.3",
@ -22,7 +23,7 @@
"typescript": "~3.7.2" "typescript": "~3.7.2"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "set PORT=3000&&react-scripts start",
"build": "react-scripts build", "build": "react-scripts build",
"test": "react-scripts test", "test": "react-scripts test",
"eject": "react-scripts eject" "eject": "react-scripts eject"

@ -1,10 +1,55 @@
import React from "react"; import React from "react";
import {Button, Tab, Table, Tabs} from "react-bootstrap"; import {Button, Form, ListGroup, Tab, Table, Tabs} from "react-bootstrap";
import {ActiveForm, ManagerActivity} from "./entity"; import {ManagerActivity} from "./entity";
import {Method, request} from "./interface"; import {JSONResponse, Method, request} from "./interface";
import {API} from "./api"; import {API} from "./api";
import {FindActivityRes, FindActivityTransform, PageDataMessage} from "./result"; import {EmptyBodyTransform, FindActivityRes, FindActivityTransform, PageDataMessage, SimpleMessage} from "./result";
import {MyDialog} from "./ui/MyDialog"; import {MyDialog} from "./ui/MyDialog";
import moment from "moment";
import {Input} from "./ui/InputGroup";
const contentMaxLength=50
class EditActive extends React.Component<
{
onClick:Function;
activity:ManagerActivity;
},
{
activity:ManagerActivity;
}>{
constructor(props: Readonly<{ onClick: Function; activity: ManagerActivity }>) {
super(props);
this.state={
activity:this.props.activity
}
}
render() {
return (
<Form>
<Input name="title" desc="活动标题" value={this.state.activity.title} onChange={(value:string)=>
this.setState({
activity:{...this.state.activity,...{title:value}}
})} valid={{check:this.isNotEmpty(this.state.activity.title)}}/>
<Input name="content" desc="活动内容" value={this.state.activity.content} as="textarea" valid=
{{check:this.state.activity.content.length>0,valid:this.state.activity.content.length===0?
"验证失败":"您还可输入"+(contentMaxLength-this.state.activity.content.length+"个字符")}}
maxLength={contentMaxLength} onChange={(value:string)=>this.setState({activity:{...this.state.activity,...{content:value}}})}/>
<Button variant={"info"} block={true} className="ml-auto mr-auto col-3 mt-3" onClick={()=>this.props.onClick(this.state.activity)}></Button>
</Form>
);
}
private isNotEmpty(name: any) {
return String(name).length>0;
}
}
/** /**
* *
@ -12,6 +57,7 @@ import {MyDialog} from "./ui/MyDialog";
export class Active extends React.Component<any, { export class Active extends React.Component<any, {
activeList?:Array<ManagerActivity>; activeList?:Array<ManagerActivity>;
tipContent:JSX.Element|null tipContent:JSX.Element|null
dialog:JSX.Element|null
}>{ }>{
@ -19,7 +65,8 @@ export class Active extends React.Component<any, {
super(props); super(props);
this.state={ this.state={
tipContent:null tipContent:null,
dialog:null
} }
} }
@ -61,24 +108,42 @@ export class Active extends React.Component<any, {
<th>#</th> <th>#</th>
<th></th> <th></th>
<th></th> <th></th>
<th></th>
<th></th>
<th>id</th>
<th>id</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{this.state.activeList?this.state.activeList.length>0?this.state.activeList.map((active:ActiveForm,index:number)=> {this.state.activeList?this.state.activeList.length>0?this.state.activeList.map((active:ManagerActivity,index:number)=>
<tr key={"tr"+index}> <tr key={"tr"+index}>
<td>{index+1}</td> <td>{index+1}</td>
<td>{active.title}</td> <td>{active.title}</td>
<td>{active.content}</td> <td>{active.content}</td>
<td>{moment(active.activityStartTime).format("YYYY-MM-DD HH:mm:ss")}</td>
<td>{moment(active.activityEndTime).format("YYYY-MM-DD HH:mm:ss")}</td>
<td>{active.seekHelpUser}</td>
<td> <td>
{/*<Button variant="danger">删除</Button>*/} {active.helpUser != null ?
<ListGroup>
{active.helpUser.map((userId,index) =>
<ListGroup.Item key={'item'+index}>{userId}</ListGroup.Item>)}
</ListGroup>:'无'
}
</td> </td>
<td><Button variant={"info"} onClick={()=>this.setState({
dialog:<MyDialog content={<EditActive onClick={(activity:ManagerActivity)=>this.modifyActivity(activity)} activity={active}/>} open={true} titleId={"activity-dialog"} menuName={"修改活动信息"}
onClose={()=>this.setState({dialog:null})}/>
})}></Button></td>
</tr> </tr>
):<h3 className="text-center text-info"></h3>:null ):<h3 className="text-center text-info"></h3>:null
} }
</tbody> </tbody>
</Table> </Table>
{this.state.dialog}
<MyDialog content={this.state.tipContent} open={this.state.tipContent!=null} titleId={"user-dialog"} menuName={"操作提示"} <MyDialog content={this.state.tipContent} open={this.state.tipContent!=null} titleId={"user-dialog"} menuName={"操作提示"}
onClose={()=>this.setState({ onClose={()=>this.setState({
tipContent:null tipContent:null
@ -87,4 +152,32 @@ export class Active extends React.Component<any, {
</Tabs> </Tabs>
); );
} }
/**
*
* @param activity
*/
private modifyActivity(activity: ManagerActivity) {
let that=this
request(API.account.updateActivity+activity.activityId,Method.POST, {
title:activity.title,
content:activity.content
},
new EmptyBodyTransform(),function (res:JSONResponse<SimpleMessage>) {
switch (res.customResult) {
case SimpleMessage.ok:
that.setState({
tipContent:<h3 className="text-info text-center"></h3>,
dialog:null
})
that.loadActive(1)
break
case SimpleMessage.fail:
that.setState({
tipContent:<h3 className="text-danger text-center"></h3>
})
break
}
})
}
} }

@ -5,6 +5,7 @@ import {User} from "./User";
import {Active} from "./Active"; import {Active} from "./Active";
import {Cookies} from "react-cookie"; import {Cookies} from "react-cookie";
import {manager_cookie} from "./account/PropCookie"; import {manager_cookie} from "./account/PropCookie";
import {fontEnd} from "./api";
/** /**
* *
@ -78,7 +79,7 @@ export class Main extends React.Component<
<Navbar.Text> <Navbar.Text>
{this.props.cookies.get(manager_cookie)} {this.props.cookies.get(manager_cookie)}
</Navbar.Text> </Navbar.Text>
<Button variant="outline-info" className="ml-3" onClick={()=>window.location.href=fontEnd}></Button>
<Button variant="outline-primary" className="ml-3" onClick={()=>this.props.logout()}></Button> <Button variant="outline-primary" className="ml-3" onClick={()=>this.props.logout()}></Button>
</Navbar> </Navbar>
{this.state.subMenu} {this.state.subMenu}

@ -6,39 +6,136 @@ import {JSONResponse, Method, request} from "./interface";
import {API, prefix} from "./api"; import {API, prefix} from "./api";
import {EmptyBodyTransform, FindUserRes, FindUserTransform, PageDataMessage, SimpleMessage} from "./result"; import {EmptyBodyTransform, FindUserRes, FindUserTransform, PageDataMessage, SimpleMessage} from "./result";
import {MyDialog} from "./ui/MyDialog"; import {MyDialog} from "./ui/MyDialog";
import {Address} from "./ui/Address";
class EditUser extends React.Component<{ class EditUser extends React.Component<{
user:UserEntity; user:UserEntity;
modifyUser:Function; modifyUser:Function;
}, { }, {
user:UserEntity; user:UserEntity;
tipContent:JSX.Element|null;
}>{ }>{
private ages:Array<number>
constructor(props: Readonly<{ user: UserEntity ,modifyUser:Function;}>) { constructor(props: Readonly<{ user: UserEntity ,modifyUser:Function;}>) {
super(props); super(props);
this.ages=this.createAge()
this.state={ this.state={
user:this.props.user, user:this.props.user
tipContent:null
} }
} }
render() { render() {
return ( return (
<Form> <Form>
<Input name="name" desc="姓名" value={this.state.user.name} onChange={(value:string)=>this.setState({ <Input name="name" desc="姓名" value={this.state.user.name} onChange={(value:string)=>
this.setState({
user:{...this.state.user,...{name:value}} user:{...this.state.user,...{name:value}}
})}/> })} valid={{check:this.isNotEmpty(this.state.user.name)}}/>
<Input col={4} name="age" desc="年龄" value={this.state.user.age+""} onChange={(value:string)=>
this.setState({
user:{...this.state.user,...{age:+value}}
})
} as={"select"} options={this.ages.map(value=><option key={value} value={value}>{value}</option>)}/>
<Input col={4} name="sex" desc="性别" as="select" value={this.state.user.sex} onChange={(value:string)=>{
this.setState({
user:{...this.state.user,...{sex:value}}
})
}}
options={[
<option value="" key={"sex"+0}></option>,
<option value="man" key={"sex"+1}></option>,
<option value="women" key={"sex"+2}></option>]}/>
<Input name="address" desc="住址" value={this.state.user.address} onChange={(value:string)=>this.setState({
user:{...this.state.user,...{address:value}}
})} valid={{check:this.isNotEmpty(this.state.user.address)}}/>
<div className="mt-3">
<Address value={this.state.user.serviceAddress} onChange={(value:string)=>
this.setState({
user:{...this.state.user,...{serviceAddress:value}}
})
}/>
</div>
<Input col={4} name="userType" desc="用户身份" as="select" value={this.state.user.userType} onChange={(value:string)=>
this.setState({
user:{...this.state.user,...{userType:value}}
})
}
options={[<option value="" key={"userType0"}></option>,
<option key={"userType1"} value={UserType.seekHelp}></option>,
<option key={"userType2"} value={UserType.help}></option>]}/>
<Input col={4} name="mobile" desc="电话" value={this.state.user.mobile} onChange={(value:string)=>
this.setState({
user:{...this.state.user,...{mobile:value}}
})
} valid={{check:this.checkMobile()}}/>
<Button variant="info" block={true} className={"ml-auto mr-auto mt-3 col-3"} onClick={()=>this.props.modifyUser(this.state.user)}></Button> <Input col={4} name="email" value={this.state.user.email} desc="邮箱" onChange={(value:string)=>
this.setState({
user:{...this.state.user,...{email:value}}
})
} valid={{check:this.checkEmail()}}/>
<Input col={7} name="info" desc="简介" value={this.state.user.info} as={"textarea"} onChange={(value:string)=>
this.setState({
user:{...this.state.user,...{info:value}}
})
}
valid={{check:this.isNotEmpty(this.state.user.info)}}/>
<Button variant="info" block={true} disabled={!this.check()} className={"ml-auto mr-auto mt-3 col-3"} onClick={()=>this.props.modifyUser(this.state.user)}></Button>
</Form> </Form>
); );
} }
private createAge(){
let age=[]
for(let i=18;i<100;i++){
age.push(i)
}
return age
}
/**
*
*/
checkMobile(){
return /1[3456789]\d{9}/g.test(this.state.user.mobile.toString())
}
/**
*
*/
private checkEmail() {
return /[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}/g.test(this.state.user.email)
}
//检查是否为空
isNotEmpty(...value:(string | number)[]){
for(let index in value){
if(value[index].toString().length===0){
return false
}
}
return true
}
private check() {
return this.isNotEmpty(this.state.user.userId,this.state.user.name,this.state.user.sex,
this.state.user.serviceAddress,this.state.user.userType,this.state.user.info)
&&this.checkMobile()&&this.checkEmail()
}
} }
/** /**
@ -107,14 +204,16 @@ export class User extends React.Component<
<th>#</th> <th>#</th>
<th></th> <th></th>
<th></th> <th></th>
<th></th>
<th></th> <th></th>
<th></th>
<th></th>
<th></th> <th></th>
<th></th>
<th></th>
<th></th> <th></th>
<th></th> <th></th>
<th></th>
<th></th> <th></th>
<th></th> <th></th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
@ -124,8 +223,9 @@ export class User extends React.Component<
<td className="align-middle">{index+1}</td> <td className="align-middle">{index+1}</td>
<td className="align-middle">{user.userId}</td> <td className="align-middle">{user.userId}</td>
<td className="align-middle">{user.name}</td> <td className="align-middle">{user.name}</td>
<td className="align-middle">{user.sex}</td>
<td className="align-middle">{user.age}</td> <td className="align-middle">{user.age}</td>
<td className="align-middle">{user.sex==='man'?'男':'女'}</td>
<td className="align-middle">{user.address}</td>
<td className="align-middle"> <td className="align-middle">
{<Image className="head-img" src={prefix.image+user.headImg} onClick={()=>this.setState({ {<Image className="head-img" src={prefix.image+user.headImg} onClick={()=>this.setState({
dialog:<MyDialog content={<Image src={prefix.image + user.headImg}/>} dialog:<MyDialog content={<Image src={prefix.image + user.headImg}/>}
@ -135,9 +235,11 @@ export class User extends React.Component<
})}/> })}/>
})}/>} })}/>}
</td> </td>
<td className="align-middle">{user.serviceAddress}</td>
<td className="align-middle">{user.userType===UserType.seekHelp?'服务发起者':'服务接受者'}</td>
<td className="align-middle">{user.mobile}</td> <td className="align-middle">{user.mobile}</td>
<td className="align-middle">{user.email}</td> <td className="align-middle">{user.email}</td>
<td className="align-middle">{user.address}</td>
<td className="align-middle">{user.timeScore}</td> <td className="align-middle">{user.timeScore}</td>
<td className="align-middle">{user.info}</td> <td className="align-middle">{user.info}</td>
<td className="align-middle"> <td className="align-middle">
@ -173,7 +275,16 @@ export class User extends React.Component<
let that=this let that=this
request(API.account.updateUser,Method.POST, { request(API.account.updateUser,Method.POST, {
userId:user.userId, userId:user.userId,
name:user.name name:user.name,
age:String(user.age),
sex:String(user.sex),
address:user.address,
serviceAddress:user.serviceAddress,
userType:user.userType,
mobile:user.mobile,
email:user.email,
info:user.info
},new EmptyBodyTransform(),function (res:JSONResponse<SimpleMessage>) { },new EmptyBodyTransform(),function (res:JSONResponse<SimpleMessage>) {
switch (res.customResult) { switch (res.customResult) {
case SimpleMessage.ok: case SimpleMessage.ok:

@ -6,6 +6,8 @@ export const prefix={
user:'/api/user', user:'/api/user',
image: "/image/" image: "/image/"
} }
//用户前台地址
export const fontEnd="http://localhost:3001"
//接口地址 //接口地址
export const API={ export const API={
@ -25,7 +27,9 @@ export const API={
// 更新用户信息 // 更新用户信息
updateUser:prefix.manager+'/userUpdate', updateUser:prefix.manager+'/userUpdate',
//查询活动信息 //查询活动信息
findActivity:prefix.manager+'/find/activity' findActivity:prefix.manager+'/find/activity',
//修改活动信息
updateActivity:prefix.manager+'/update/'
}, },
user:{ user:{

@ -172,7 +172,7 @@ export enum UserType {
seekHelp="seekHelp", seekHelp="seekHelp",
help="help" help="help"
} }
//活动列表
export interface ManagerActivity { export interface ManagerActivity {
activityId:number; activityId:number;
content:string; content:string;
@ -184,3 +184,16 @@ export interface ManagerActivity {
helpUser:Array<string>; helpUser:Array<string>;
} }
/**
*
*/
export interface AddressProps {
address:string;
}
export interface OnChangeAddress {
onChange:Function;
col?:number;
value?:string;
}

@ -0,0 +1,56 @@
import {Form, InputGroup} from "react-bootstrap";
import {AddressProps, OnChangeAddress} from "../entity";
import React from "react";
/**
*
*/
export class Address extends React.Component<OnChangeAddress, { addressList:Array<{ address:string }> }>{
constructor(props: Readonly<OnChangeAddress>) {
super(props);
this.state={
addressList:[],
}
}
componentDidMount() {
this.loadAddress()
}
/**
*
*/
loadAddress(){
this.setState({
addressList:[{
address:"北京",
},
{
address:"广州",
},
{
address:"上海",
}]
})
}
render() {
return (
<InputGroup className={"col-"+(this.props.col?this.props.col:3)+" ml-auto mr-auto"}>
<InputGroup.Prepend>
<InputGroup.Text></InputGroup.Text>
</InputGroup.Prepend>
<Form.Control as="select" value={this.props.value} custom onChange={(e)=>this.props.onChange(e.target.value)}>
<option value=""></option>
{this.state.addressList.map((address:AddressProps, index:number)=>
<option key={"option"+index} value={address.address} >{address.address}</option>
)}
</Form.Control>
</InputGroup>
)
}
}

@ -1,10 +1,14 @@
import React from "react"; import React from "react";
import Dialog from "@material-ui/core/Dialog"; import Dialog from "@material-ui/core/Dialog";
import Draggable from "react-draggable"; import Draggable from "react-draggable";
import {Paper} from "@material-ui/core"; import {Paper, styled, withWidth} from "@material-ui/core";
import {MyDialogProps} from "../entity"; import {MyDialogProps} from "../entity";
import {CloseDialog} from "./CloseDialog"; import {CloseDialog} from "./CloseDialog";
const EditDialogPaper=styled(Paper)({
maxWidth:1000
})
/** /**
* *
*/ */
@ -18,7 +22,7 @@ export class MyDialog extends React.Component<MyDialogProps, { undefined?:undefi
open={this.props.open} open={this.props.open}
PaperComponent={(props)=> PaperComponent={(props)=>
<Draggable handle={"#"+this.props.titleId} cancel={'[class*="MuiDialogContent-root"]'}> <Draggable handle={"#"+this.props.titleId} cancel={'[class*="MuiDialogContent-root"]'}>
<Paper {...props} /> <EditDialogPaper {...props} />
</Draggable>} </Draggable>}
aria-labelledby={this.props.titleId} aria-labelledby={this.props.titleId}
classes={{paper:"w-100"}} classes={{paper:"w-100"}}

@ -7101,6 +7101,11 @@ mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1:
dependencies: dependencies:
minimist "^1.2.5" minimist "^1.2.5"
moment@^2.26.0:
version "2.26.0"
resolved "https://registry.npm.taobao.org/moment/download/moment-2.26.0.tgz#5e1f82c6bafca6e83e808b30c8705eed0dcbd39a"
integrity sha1-Xh+Cxrr8pug+gIswyHBe7Q3L05o=
move-concurrently@^1.0.1: move-concurrently@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.npm.taobao.org/move-concurrently/download/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" resolved "https://registry.npm.taobao.org/move-concurrently/download/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"

Loading…
Cancel
Save