diff --git a/package.json b/package.json index 44cb4bd..7dd1edf 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@types/react": "^16.9.0", "@types/react-dom": "^16.9.0", "bootstrap": "^4.5.0", + "http-proxy-middleware": "^1.0.4", "moment": "^2.26.0", "react": "^16.13.1", "react-bootstrap": "^1.0.1", diff --git a/src/Main.tsx b/src/Main.tsx index 3eb5800..1382f56 100644 --- a/src/Main.tsx +++ b/src/Main.tsx @@ -104,12 +104,17 @@ export class Main extends React.Component< });break; case Menu.myHelp: this.setState({ - subMenu: + subMenu:this.onSendActivityOK()}/> });break; } } + //活动发布成功 + onSendActivityOK(){ + this.changeMenu(Menu.index) + } + /** * 关闭弹窗 */ diff --git a/src/account/Login.tsx b/src/account/Login.tsx index 56fe8a1..eee235f 100644 --- a/src/account/Login.tsx +++ b/src/account/Login.tsx @@ -29,9 +29,7 @@ export class Login extends React.Component{ request(API.account.login,Method.POST,{ userId:this.state.userId, password:this.state.password - },function () { - return new LoginTransform() - },function (res:LoginRes) { + },new LoginTransform(),function (res:LoginRes) { let message switch (res.customResult) { case LoginResMessage.ok: diff --git a/src/account/Register.tsx b/src/account/Register.tsx index f2d19c2..a336d6e 100644 --- a/src/account/Register.tsx +++ b/src/account/Register.tsx @@ -57,9 +57,7 @@ export class Register extends React.Component{ email:this.state.email, info:this.state.info - },function () { - return new RegisterTransform() - },function(res:RegisterRes){ + },new RegisterTransform(),function(res:RegisterRes){ let message switch (res.customResult) { case RegisterMessage.ok:message="注册成功"; diff --git a/src/entity.ts b/src/entity.ts index 8628a99..84c4747 100644 --- a/src/entity.ts +++ b/src/entity.ts @@ -48,19 +48,21 @@ export enum RecommendType { * 活动简介 */ export interface BaseHelp { - //活动ID - activityId:number; //活动标题 title:string; //活动内容 content:string; //活动背景图 - activityImg:string; + activityImg?:string; } +export interface ActivityId { + //活动ID + activityId:number; +} //活动详情 -export interface ActivityDetail extends BaseHelp{ +export interface ActivityDetail extends BaseHelp,ActivityId{ //活动开始时间 activityStartTime:number; //活动结束时间 @@ -68,13 +70,9 @@ export interface ActivityDetail extends BaseHelp{ } //我的帮助信息 -export interface MyHelpState extends BaseHelp{ +export interface MyHelpState extends ActivityDetail{ //求助时间 seekHelpTime:number; - //活动开始时间 - activityStartTime:number; - //活动结束时间 - activityEndTime:number; //报名时间 applyTime:number; //参与时间 @@ -87,7 +85,7 @@ export interface MyHelpState extends BaseHelp{ //我的求助信息 -export interface SeekHelpState extends BaseHelp{ +export interface SeekHelpState extends BaseHelp,ActivityId{ //求助时间 time:number; //活动报名志愿者 @@ -98,16 +96,18 @@ export interface SeekHelpState extends BaseHelp{ completeVolunteerList:Array; } + + /** - * 求助信息 + * 发布求助信息 */ export interface SendHelpState extends BaseHelp{ - //开始时间 - startTime:string; - //结束时间 - endTime:string; + //活动开始时间 + activityStartTime:string; + //活动结束时间 + activityEndTime:string; //服务地点 - address:string; + serviceAddress:string; //推荐方式 recommendType:RecommendType; //好友列表 @@ -116,6 +116,8 @@ export interface SendHelpState extends BaseHelp{ chooseFriendList: { [propName:string]:User }; + activityImgFile?:any; + result:JSX.Element|null; } diff --git a/src/interface.ts b/src/interface.ts index 22341ce..561e789 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -3,13 +3,24 @@ const server="http://localhost:8080" const prefix={ - user:"/api/user" + user:"/api/user", + activity:"/api/activity" } //服务器接口地址 export const API={ account:{ + //注册 register:prefix.user+"/register", + //登录 login:prefix.user+"/login" + }, + main:{ + activity: { + //发布求助信息 + help: prefix.activity + "/sendHelp", + //查找活动列表 + find: prefix.activity + "/find" + } } } @@ -20,8 +31,8 @@ export enum Method { } export enum Result { - OK, - FAIL + OK="OK", + FAIL="FAIL" } @@ -66,14 +77,22 @@ export abstract class TransformData> { } //发送请求 -export function request,T extends TransformData>(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]) +export function request,T extends TransformData>(api:string,method:Method,formParams: {[propName:string]: string | Blob},transform:T,callback:Function) { + let formData + if(method!==Method.GET) { + formData=new FormData() + for (let formParam in formParams) { + formData.append(formParam, formParams[formParam]) + } + }else{ + formData='' + for (let formParam in formParams) { + formData+='&'+formParam+'='+formParams[formParam] + } } - fetch(server+api,{ + fetch(server+api+(method===Method.GET?"?"+formData.toString().substr(1):""),{ method:method, - body:formData + body:method===Method.GET?null:formData }) .then( response=>{if(response.status===200){ @@ -87,7 +106,6 @@ export function request,T extends TransformData error =>console.error('Error:', error) ) .then((response:JSONResponse)=>{ - let transform:T=transformFun() callback(transform.transform(response)) }) } diff --git a/src/my/MyLeaveWord.tsx b/src/my/MyLeaveWord.tsx index 1c14045..057fe4a 100644 --- a/src/my/MyLeaveWord.tsx +++ b/src/my/MyLeaveWord.tsx @@ -5,7 +5,7 @@ import {Tooltip} from "@material-ui/core"; import {MyDialog} from "../ui/MyDialog"; import {MyInfo} from "./MyInfo"; import {Activity} from "../ui/Activity"; -import {userObj} from "../ui/TestData"; +import {activityObj, userObj} from "../ui/TestData"; enum LeaveWordType { recommend, @@ -62,26 +62,12 @@ export class MyLeaveWord extends React.Component<{ user:string }, data:[ { user:userObj, - activity:{ - activityId:1, - title:"活动标题1", - content:"活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动", - activityImg:"logo512.png", - activityStartTime:new Date().getTime(), - activityEndTime:new Date().getTime() - }, + activity:activityObj, type:LeaveWordType.recommend }, { user:userObj, - activity:{ - activityId:1, - title:"活动标题1", - content:"活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动", - activityImg:"logo512.png", - activityStartTime:new Date().getTime(), - activityEndTime:new Date().getTime() - }, + activity:activityObj, type:LeaveWordType.apply }, { diff --git a/src/result.ts b/src/result.ts index 4347ea2..bd6c8d0 100644 --- a/src/result.ts +++ b/src/result.ts @@ -2,7 +2,7 @@ * 返回信息 */ import {JSONResponse, Result, TransformData} from "./interface"; -import {UserType} from "./entity"; +import {ActivityDetail, PageProps, UserType} from "./entity"; /** * 注册响应信息 @@ -19,7 +19,7 @@ export enum RegisterMessage { } /** - * 注册数据载体 + * 注册响应实体 */ export class RegisterRes implements JSONResponse { customResult?: RegisterMessage; @@ -49,7 +49,7 @@ export enum LoginResMessage { } /** - * 登录响应结果转换 + * 登录响应实体 */ export class LoginRes implements JSONResponse{ userId?:string @@ -58,6 +58,9 @@ export class LoginRes implements JSONResponse{ result?: Result; } +/** + * 登录响应数据转换 + */ export class LoginTransform extends TransformData{ protected newObject(): LoginRes { return new LoginRes(); @@ -70,3 +73,68 @@ export class LoginTransform extends TransformData{ } } } + +/** + * 发布求助信息结果 + */ +export enum ActivityMessage { + //发布成功 + ok="ok", + //发布失败请联系管理员 + fail="fail" +} + +/** + * 发布求助信息响应实体 + */ +export class SendHelpRes extends JSONResponse{ + +} + +/** + * 发布求助信息响应结果转换 + */ +export class SendHelpTransform extends TransformData{ + protected newObject(): SendHelpRes { + return new SendHelpRes(); + } + +} + +/** + * 查询活动列表结果 + */ +export enum FindActivityMessage { + ok="ok", + fail="fail" +} + +/** + * 查询活动列表响应实体 + */ +export class FindActivityRes extends JSONResponse{ + dataList?:Array> + page?:PageProps +} + +/** + * 活动列表数据转换 + */ +export class FindActivityTransform extends TransformData{ + protected newObject(): FindActivityRes { + return new FindActivityRes(); + } + + + protected transformBody(data: any) { + if(data.body!==null){ + this.target.dataList=data.body.body + this.target.page={ + currentPage:data.body.currentPage, + totalPage:data.body.totalPage, + pageSize:data.body.pageSize + } + } + + } +} diff --git a/src/setupProxy.js b/src/setupProxy.js new file mode 100644 index 0000000..facc066 --- /dev/null +++ b/src/setupProxy.js @@ -0,0 +1,12 @@ +const { createProxyMiddleware } = require('http-proxy-middleware'); + +module.exports = function (app) { + app.use(createProxyMiddleware('/image', { + target: 'http://localhost:8080', + secure: false, + changeOrigin: true, + pathRewrite: { + "^/image": "/image" + } + })) +} diff --git a/src/sub/IndexMenu.tsx b/src/sub/IndexMenu.tsx index 055ec3f..691c7b5 100644 --- a/src/sub/IndexMenu.tsx +++ b/src/sub/IndexMenu.tsx @@ -2,10 +2,13 @@ import React from "react"; import {Button, Card, Col, Container, ListGroup, Row} from "react-bootstrap"; import {Page} from "../ui/Page"; -import {ActivityDetail, BaseHelp, PageProps} from "../entity"; +import {ActivityDetail, PageProps} from "../entity"; import {MyDialog} from "../ui/MyDialog"; import {Activity} from "../ui/Activity"; import {Input} from "../ui/InputGroup"; +import {activityObj} from "../ui/TestData"; +import {API, Method, request} from "../interface"; +import {FindActivityMessage, FindActivityRes, FindActivityTransform} from "../result"; /** * 首页 @@ -13,15 +16,16 @@ import {Input} from "../ui/InputGroup"; export class IndexMenu extends React.Component<{ user:string }, { //活动数据 - activityList:Array>; + activityList?:Array>; //分页信息 - page:PageProps; + page?:PageProps; //活动 activity?:ActivityDetail; //打开活动 openActivity:boolean; //检索活动标题 title:string; + result:JSX.Element|null; }>{ @@ -30,13 +34,7 @@ export class IndexMenu extends React.Component<{ user:string }, super(props); this.state={ - activityList:[], - page:{ - currentPage:1, - totalPage:3, - pageSize:9 - }, - openActivity:false, + result: null,openActivity:false, title:"" } } @@ -58,14 +56,8 @@ export class IndexMenu extends React.Component<{ user:string }, * @param activityId */ loadActivityWithId(activityId:number):ActivityDetail{ - return { - activityId:123, - activityImg:"logo512.png", - content: "活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容", - title: "标题标题标题标题标题标题标题", - activityEndTime:new Date().getTime(), - activityStartTime:new Date().getTime() - } + console.debug("activityId="+activityId) + return activityObj } /** @@ -74,68 +66,35 @@ export class IndexMenu extends React.Component<{ user:string }, */ loadActivity(page:number){ console.debug("检索活动关键字:"+this.state.title) - - this.setState({ - activityList:[[{ - activityId: 123, - //活动标题 - title: "活动标题", - //活动内容 - content: "活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容", - //活动图片 - activityImg: "/logo512.png" - },{ - activityId: 123, - //活动标题 - title: "活动标题", - //活动内容 - content: "活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容", - //活动图片 - activityImg: "/logo512.png" - },{ - activityId: 123, - //活动标题 - title: "活动标题", - //活动内容 - content: "活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容", - //活动图片 - activityImg: "/logo512.png" - }],[{ - activityId: 123, - //活动标题 - title: "活动标题", - //活动内容 - content: "活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容", - //活动图片 - activityImg: "/logo512.png" - },{ - activityId: 123, - //活动标题 - title: "活动标题", - //活动内容 - content: "活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容", - //活动图片 - activityImg: "/logo512.png" - },{ - activityId: 123, - //活动标题 - title: "活动标题", - //活动内容 - content: "活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容活动内容", - //活动图片 - activityImg: "/logo512.png" - }]] + let that=this + request(API.main.activity.find,Method.GET,{ + title:this.state.title, + currentPage:page+"" + },new FindActivityTransform(),function (res:FindActivityRes) { + + + switch(res.customResult){ + case FindActivityMessage.fail: + that.setState({ + result:

活动加载失败,请联系管理员

+ });break; + case FindActivityMessage.ok: + that.setState({ + activityList:res.dataList, + page:res.page + });break + } }) } render() { - const rowList=this.state.activityList.map((activities:Array, index:number)=> - {activities.map((activity:BaseHelp, subIndex:number)=> + const rowList=this.state.activityList?this.state.activityList.map((activities:Array, index:number)=> + {activities.map((activity:ActivityDetail, subIndex:number)=> - 活动图片 + 活动图片 @@ -157,7 +116,7 @@ export class IndexMenu extends React.Component<{ user:string }, )} - ) + ):null return ( @@ -172,13 +131,14 @@ export class IndexMenu extends React.Component<{ user:string }, {rowList} - - this.loadActivity(page)} currentPage={this.state.page.currentPage} totalPage={this.state.page.totalPage} pageSize={this.state.page.pageSize}/> + {this.state.page?this.loadActivity(page)} currentPage={this.state.page.currentPage} totalPage={this.state.page.totalPage} pageSize={this.state.page.pageSize}/>:null} {this.state.activity?this.applyActivity(activeId)} />} open={this.state.openActivity} titleId="view-active" menuName="活动详情" onClose={()=>this.setState({activity:undefined,openActivity:false})}/>:null} + this.setState({result:null})}/> + ) } diff --git a/src/sub/SendHelp.tsx b/src/sub/SendHelp.tsx index 53e4401..45995bd 100644 --- a/src/sub/SendHelp.tsx +++ b/src/sub/SendHelp.tsx @@ -8,6 +8,9 @@ import moment from 'moment'; import {Address} from "../ui/Address"; import {UploadImg} from "../ui/UploadImg"; import {userObj} from "../ui/TestData"; +import {API, Method, request} from "../interface" +import {ActivityMessage, SendHelpRes, SendHelpTransform} from "../result"; +import {MyDialog} from "../ui/MyDialog"; /** * 活动内容限长字符数 @@ -29,7 +32,7 @@ const recommendType=[RecommendType.no, RecommendType.choose,RecommendType.auto] /** * 我的求助 */ -export class SendHelp extends React.Component<{ undefined?:undefined }, SendHelpState>{ +export class SendHelp extends React.Component<{ onSendActivityOK:Function }, SendHelpState>{ //当前选中的好友索引 private friendIndex:RefObject; @@ -38,17 +41,16 @@ export class SendHelp extends React.Component<{ undefined?:undefined }, SendHelp const time=moment() this.state={ - //活动Id - activityId:123, title:"", content:"", - startTime:time.add({days:1}).format("YYYY-MM-DD HH:mm:ss"), - endTime:time.add({days:7}).format("YYYY-MM-DD HH:mm:ss"), - activityImg:"上传活动背景图", - address: "", + activityStartTime:time.add({days:1}).format("YYYY-MM-DD HH:mm:ss"), + activityEndTime:time.add({days:7}).format("YYYY-MM-DD HH:mm:ss"), + serviceAddress: "", recommendType: RecommendType.no, friendList:[], - chooseFriendList: {} + chooseFriendList: {}, + result:null + } this.friendIndex=React.createRef() @@ -79,24 +81,62 @@ export class SendHelp extends React.Component<{ undefined?:undefined }, SendHelp return RecommendType.no } + //发布求助信息 + sendHelp(){ + let that=this + request(API.main.activity.help,Method.PUT, { + title:this.state.title, + content:this.state.content, + activityStartTime:this.state.activityStartTime, + activityEndTime:this.state.activityEndTime, + activityImgFile:this.state.activityImgFile, + serviceAddress:this.state.serviceAddress + },new SendHelpTransform(),function (res:SendHelpRes) { + switch (res.customResult) { + case ActivityMessage.ok: + that.setState({ + result:
+ });break + case ActivityMessage.fail: + that.setState({ + result:

发布失败

+ });break + } + }) + } + + //检查是否为空 + isNotEmpty(...value:(string | number)[]){ + for(let index in value){ + if(value[index].toString().length===0){ + return false + } + } + return true + } + + check(){ + return this.isNotEmpty(this.state.title,this.state.content,this.state.serviceAddress)&&this.state.activityImgFile!=null + } + render() { return ( {/*活动标题*/} - this.setState({title:value})}/> + this.setState({title:value})} valid={{check:this.state.title.length>0}}/> {/*活动内容*/} - this.setState({content:value})}/> + 0,valid:this.state.content.length===0?"验证失败":"您还可输入"+(contentMaxLength-this.state.content.length+"个字符")}} maxLength={contentMaxLength} onChange={(value:string)=>this.setState({content:value})}/> {/*活动开始时间*/} 活动开始时间 - { + { if(moment.isMoment(value)){ this.setState({ - startTime:value.format("YYYY-MM-DD HH:mm:ss") + activityStartTime:value.format("YYYY-MM-DD HH:mm:ss") }) } }} dateFormat="YYYY-MM-DD" timeFormat="HH:mm:ss"/> @@ -107,21 +147,21 @@ export class SendHelp extends React.Component<{ undefined?:undefined }, SendHelp 活动结束时间 - { + { if(moment.isMoment(value)){ this.setState({ - endTime:value.format("YYYY-MM-DD HH:mm:ss") + activityEndTime:value.format("YYYY-MM-DD HH:mm:ss") }) } }} dateFormat="YYYY-MM-DD" timeFormat="HH:mm:ss"/> - this.setState({activityImg:value})} /> + this.setState({activityImgFile:value})} /> {/*服务地点*/} -
this.setState({address:value})}/> +
this.setState({serviceAddress:value})}/> - 0?"":"d-none")}> + 0?"":"d-none")}> 推荐好友方式 @@ -176,7 +216,9 @@ export class SendHelp extends React.Component<{ undefined?:undefined }, SendHelp )} - + + + this.setState({result:null})}/> ); } diff --git a/src/ui/TestData.ts b/src/ui/TestData.ts index cb5d9c2..87d0074 100644 --- a/src/ui/TestData.ts +++ b/src/ui/TestData.ts @@ -21,3 +21,12 @@ export const userObj={ flag:false, userType:UserType.seekHelp.toString() } + +export const activityObj={ + activityId:0, + title:"活动标题1", + content:"活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动活动内容活动内容活动", + activityImg:"logo512.png", + activityStartTime:new Date().getTime(), + activityEndTime:new Date().getTime() +} diff --git a/yarn.lock b/yarn.lock index 8a68270..4d464de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1556,6 +1556,13 @@ "@types/react" "*" hoist-non-react-statics "^3.3.0" +"@types/http-proxy@^1.17.4": + version "1.17.4" + resolved "https://registry.npm.taobao.org/@types/http-proxy/download/@types/http-proxy-1.17.4.tgz#e7c92e3dbe3e13aa799440ff42e6d3a17a9d045b" + integrity sha1-58kuPb4+E6p5lED/QubToXqdBFs= + dependencies: + "@types/node" "*" + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": version "2.0.2" resolved "https://registry.npm.taobao.org/@types/istanbul-lib-coverage/download/@types/istanbul-lib-coverage-2.0.2.tgz#79d7a78bad4219f4c03d6557a1c72d9ca6ba62d5" @@ -2566,7 +2573,7 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -braces@~3.0.2: +braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha1-NFThpGLujVmeI23zNs2epPiv4Qc= @@ -5310,7 +5317,18 @@ http-proxy-middleware@0.19.1: lodash "^4.17.11" micromatch "^3.1.10" -http-proxy@^1.17.0: +http-proxy-middleware@^1.0.4: + version "1.0.4" + resolved "https://registry.npm.taobao.org/http-proxy-middleware/download/http-proxy-middleware-1.0.4.tgz?cache=0&sync_timestamp=1589915518285&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-proxy-middleware%2Fdownload%2Fhttp-proxy-middleware-1.0.4.tgz#425ea177986a0cda34f9c81ec961c719adb6c2a9" + integrity sha1-Ql6hd5hqDNo0+cgeyWHHGa22wqk= + dependencies: + "@types/http-proxy" "^1.17.4" + http-proxy "^1.18.1" + is-glob "^4.0.1" + lodash "^4.17.15" + micromatch "^4.0.2" + +http-proxy@^1.17.0, http-proxy@^1.18.1: version "1.18.1" resolved "https://registry.npm.taobao.org/http-proxy/download/http-proxy-1.18.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-proxy%2Fdownload%2Fhttp-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" integrity sha1-QBVB8FNIhLv5UmAzTnL4juOXZUk= @@ -6963,6 +6981,14 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.npm.taobao.org/micromatch/download/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha1-T8sJmb+fvC/L3SEvbWKbmlbDklk= + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.npm.taobao.org/miller-rabin/download/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" @@ -7829,7 +7855,7 @@ performance-now@^2.1.0: resolved "https://registry.npm.taobao.org/performance-now/download/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picomatch@^2.0.4, picomatch@^2.2.1: +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.npm.taobao.org/picomatch/download/picomatch-2.2.2.tgz?cache=0&sync_timestamp=1584790434095&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpicomatch%2Fdownload%2Fpicomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha1-IfMz6ba46v8CRo9RRupAbTRfTa0=