一、搜索Search

    

  • 搜索框

    <Search placeholder="请输入关键字"
    defaultValue={kw && kw != 'null' ? kw : ''}
    className={styles.search}
    onChange={() => this.handleKwChange()}
    onSearch={(e) => this.handleSearch(e)}
    />
  • 引入工具方法:去掉收尾空格

    import {trimStr} from '@/utils/utils';
    
    // utils.js
    export function trimStr(str){
    return str.replace(/(^\s*)|(\s*$)/g,"");
    }
  • 搜索按钮触发搜索方法,输入内容改变自动搜索

    handleSearch = e => {
    const { dispatch } = this.props;
    const { currentPage } = this.state;
    let kw = trimStr(e);
    this.setState({ keyword : kw });
    dispatch({
    type: 'newMallOrder/fetch',
    payload: {
    currentPage,
    e: {
    keyword: kw
    },
    showCount: 10
    },
    });
    }; handleKwChange = () => {
    const { dispatch } = this.props;
    const { currentPage } = this.state;
    if(event && event.target && event.target.value){
    let value = event.target.value;
    this.handleSearch(value)
    }else{
    dispatch({
    type: 'newMallOrder/fetch',
    payload: {
    currentPage,
    e: {
    keyword: null
    },
    showCount: 10
    },
    });
    }
    }

二、选择器Select & TreeSelect

        

  • 表单中嵌入Select选择器

    <FormItem>
    {getFieldDecorator('tempTypeId',{
    initialValue: 0
    })(
    <Select placeholder="请选择" style={{ width: '100%' }}
    onChange={this.handleTempType}>
    <Option value={0}>H5在线编辑</Option>
    <Option value={1}>贺卡</Option>
    <Option value={2}>海报</Option>
    <Option value={3}>壁纸</Option>
    <Option value={4}>全部</Option>
    </Select>
    )}
    </FormItem>

    选择方法:

    handleTempType = value => {
    const { dispatch } = this.props;
    const { keyword } = this.state; this.setState({
    tempType: tempTypeMap[value]
    })
    dispatch({
    type: 'temp/fetch',
    payload: {
    currentPage: 1,
    e: {
    keyword: keyword,
    subjectClass: tempTypeMap[value]
    },
    showCount: 2
    }
    });
    dispatch({
    type: 'temp/fetchType',
    payload: {
    ofClass: tempTypeMap[value]
    },
    callback: (res) => {
    if(res.code == 200){
    let typeList = res.data; // 获取联动选择框的数据 typeList.forEach((typeItem, index) => {
    dispatch({
    type: 'temp/fetchThirdType',
    payload: typeItem.id,
    callback: (res) => {
    if(res.code == 200 && res.data.length){
    typeList[index].list = res.data;
    }
    }
    })
    })
    setTimeout(() => this.setState({ typeList }), 0)
    }
    }
    });
    }
  • 联动选择的第一个选择框的父级数据
    let ParentTypeData = [
    {
    title: 'H5在线编辑',
    value: 0,
    key: 0,
    },
    {
    title: '贺卡',
    value: 1,
    key: 1,
    },
    {
    title: '海报',
    value: 2,
    key: 2,
    },
    {
    title: '壁纸',
    value: 3,
    key: 3,
    },
    {
    title: '全部',
    value: 4,
    key: 4,
    },
    ];
  • 处理获取到的联动选择第二个选择框的数据为TreeSelect需要的数据格式
    let typeData = [];
    const typeTree = (typeList, typeData) => {
    if(typeList.length) {
    for(let i=0; i<typeList.length; i++){
    typeData[i] = {
    title: typeList[i].kind,
    value: typeList[i].id,
    key: typeList[i].id
    }
    //二级分类
    if(typeList[i].list){
    typeData[i].children = [];
    typeTree(typeList[i].list, typeData[i].children)
    }
    }
    }
    }
    typeTree(typeList, typeData);
  • 表单中嵌入TreeSelect选择器

     <FormItem label="主题类别" {...formLayout}>
    <TreeSelect
    defaultValue={tempType == null ? 4 : tempTypeMap.indexOf(tempType)}
    value={parentTypeId}
    style={{display: `${editDisable ? 'none' : 'inline-block'}`, width: '47%', marginRight: '6%'}}
    dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
    treeData={ParentTypeData}
    placeholder="请选择"
    onChange={handleParentType}
    />
    {form.getFieldDecorator('typeIds', {
    rules: [{ type:"array", required: true, message: '请选择主题类别'}],
    initialValue: detail.types && detail.types.length
    ? detail.types.map((type) => type.id)
    : []
    })(
    <TreeSelect
    multiple // 多选
    style={{width: `${editDisable ? '100%' : '47%'}`}}
    dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
    treeData={typeData}
    placeholder="请选择"
    disabled={editDisable}
    onChange={handleTypeChange}
    />
    )}
    </FormItem>

三、图片视频音频上传Upload

  • 弹框表单中上传一张图片、一个音频

  1. 引入upload.js中封装的handImageUpload文件上传七牛云的方法

    import { handleImageUpload } from '@/utils/upload';
    
    // 预览文件时url前面需要加七牛云服务器前缀
    // eg: 'http://fileserver.liuliu123.cn/'
    import { setFileHost } from '@/utils/utils';

    upload.js

    var qiniu = require('qiniu-js')
    import axios from 'axios';
    import configs from '@/utils/env'
    import { message } from 'antd'; //七牛云上传,input, onchange事件
    export function handleImageUpload(file, type, resName) {
    // console.log(file,'handleImageUpload')
    let suffix = file.type.split('/')[1]; return new Promise(function(resolve, reject){ if(!file) {
    reject('file is undefined')
    } function dataURItoBlob(base64Data) {
    var byteString;
    if(base64Data.split(',')[0].indexOf('base64') >= 0)
    byteString = atob(base64Data.split(',')[1]);
    else
    byteString = unescape(base64Data.split(',')[1]);
    var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0];
    var ia = new Uint8Array(byteString.length);
    for(var i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ia], {
    type: mimeString
    });
    } function randomString(len) {
    len = len || 32;
    var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
    var maxPos = $chars.length;
    var pwd = '';
    for (let i = 0; i < len; i++) {
    pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
    }
    return pwd;
    } var reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function(e) { var fileBlob = dataURItoBlob(e.target.result);
    var key;
    switch(type){
    case 'audio':
    key = 'sys/file/music/' + resName + '.' + suffix;
    break;
    case 'video':
    key = 'liveWallPaper/' + resName + '.' + suffix;
    break;
    case 'tutorial': //教程文件
    key = 'sys/tutorial/' + new Date().getTime() + randomString(5) + '.' + suffix;
    break;
    case 'tutorialVideo': //针对IOS富文本视频显示问题单独处理教程视频
    key = 'yihezo/' + new Date().getTime() +randomString(5) + '.' + suffix;
    break;
    default:
    key = 'user/h5/' + new Date().getTime() +randomString(5) + '.' + suffix;
    } var putExtra = {
    fname: file.name,
    params: {},
    mimeType: ["image/png", "image/jpeg", "image/jpg", "image/gif", "image/webp", "image/apng", "image/svg",
    "audio/mp3", "audio/mp4", "audio/ogg", "audio/mpeg",
    "video/mp4", "video/ogg", "video/webm"]
    }; var config = {
    useCdnDomain: true,
    }; if(type == 'tutorialVideo' ){ //针对IOS富文本视频显示问题单独处理教程视频
    axios.post(configs[process.env.API_ENV]['BG_SERVER']+'/file/qiniu/token/video', {
    key: 'yihezo/' + new Date().getTime() +randomString(5) //入参:教程视频的key
    }, {
    headers: {
    AuthorizationToken: localStorage.getItem('login_token')
    }
    }).then(res =>{
    let {data} = res;
    if(data.code == 200) {
    let token = data.data.token;
    let observable = qiniu.upload(fileBlob, key, token, putExtra, config) let subscription = observable.subscribe({next(res){
    // console.log(res, 'loading')
    }, error(res){
    message.error('上传失败');
    }, complete(res) {
    resolve(res.key)
    }})
    //subscription.unsubscribe() // 上传取消 } else {
    message.error('获取七牛云token失败');
    }
    }).catch(error => {
    console.error(error)
    reject(error)
    }) }else{
    axios.post(configs[process.env.API_ENV]['BG_SERVER']+'/file/qiniu/token', {}, {
    headers: {
    AuthorizationToken: localStorage.getItem('login_token')
    }
    }).then(res =>{
    let {data} = res;
    if(data.code == 200) {
    let token = data.data.token;
    let observable = qiniu.upload(fileBlob, key, token, putExtra, config) let subscription = observable.subscribe({next(res){
    // console.log(res, 'loading')
    }, error(res){
    message.error('上传失败');
    }, complete(res) {
    resolve(res.key)
    }})
    //subscription.unsubscribe() // 上传取消 } else {
    message.error('获取七牛云token失败');
    }
    }).catch(error => {
    console.error(error)
    reject(error)
    })
    } }
    }) }
  2. state中定义初始值
    fileThumb: null,      // 存储上传七牛云后返回的图片url
    fileUri: null, // 存储上传七牛云后返回的文件url
    fileVisible: false, // 控制预览文件的弹框是否visible
    previewVisible: false,// 控制预览图片的弹框是否visible
    previewImage: '', //预览要上传的图片和上传后的图片的url
    previewFile: '' //预览要上传的图片和上传后的图片的url
  3. 弹框表单中Upload组件

    // 上传按钮
    const ImgUpButton = (
    <div>
    <Icon type="plus" />
    <div className="ant-upload-text">Upload</div>
    </div>
    ); const FileUpButton = (
    <Button>
    <Icon type="upload" /> Upload
    </Button>
    )
    <FormItem label="资源图片" {...this.formLayout}>
    {
    getFieldDecorator('thumb', {
    rules: [{ required: true, message: '请上传图片' }],
    initialValue: current.thumb ? [{ // 默认必须是数组
    uid: '-1',
    status: 'done',
    name: current.resName,
    url: `${setFileHost()+current.thumb}`,
    thumbUrl: `${setFileHost()+current.thumb}`
    }] : "" // 无值时必须是空串
    })(
    <div>
    <Upload
    accept="image/*" // 限制上传的文件类型
    action={(file) => handleImageUpload(file, 'image').then(res => {
    const newFileThumb = [];
    newFileThumb.push(res);
    this.setState({
    fileThumb: newFileThumb,
    })
    })} // 上传七牛云后存储url
    listType="picture-card"
    fileList={imgList} // 显示的图片数组
    onRemove={this.handleImgRemove}
    onPreview={this.handleImgPreview}
    onChange={this.handleImgChange}
    >
    {imgList.length >= 1 ? null : ImgUpButton}
    </Upload>
    <Modal visible={previewVisible} footer={null} onCancel={this.handleImgCancel}>
    <img alt="资源图片" style={{ width: '100%' }} src={previewImage} />
    </Modal>
    </div>
    )}
    </FormItem>
    <FormItem label="资源文件" extra={resNameError || resName == null ? <span style={{color:'#1890FF'}}>请先输入资源名称</span> : ''} {...this.formLayout}>
    {getFieldDecorator('uri', {
    rules: [{ required: true, message: '请上传文件' }],
    initialValue: current.uri ? [{
    uid: '-1',
    status: 'done',
    name: current.uri,
    url: `${setFileHost()+current.uri}`
    }] : ""
    })(
    <div>
    <Upload
    accept="audio/mp3, audio/mp4, audio/ogg, audio/mpeg"
    disabled={ resNameError || resName == null ? true : false }
    action={(file) => handleImageUpload(file, 'audio', resName).then(res => {
    const newFileUri = [];
    newFileUri.push(res);
    this.setState({
    fileUri: newFileUri
    })
    })}
    fileList={fileList}
    onRemove={this.handleFileRemove}
    onPreview={this.handleFilePreview}
    onChange={this.handleFileChange}
    >
    {fileList.length >= 1 ? null : FileUpButton}
    </Upload>
    <Modal visible={fileVisible} footer={null} onCancel={this.handleFileCancel} style={{textAlign: 'center'}}>
    <audio src={previewFile} style={{ width: '80%' }} controls="controls" autoPlay="autoplay">
    您的浏览器不支持 audio 标签。
    </audio>
    </Modal>
    </div>
    )}
    </FormItem>
    // 上传图片 使用的方法
    // 删除、预览弹框关闭、预览图片url和预览弹框打开,存储改变的图片url
    handleImgRemove = () => {
    this.setState({
    imgList: [],
    fileThumb: [''],
    })
    return true
    } handleImgCancel = () => this.setState({ previewVisible: false }) handleImgPreview = (file) => {
    this.setState({
    previewImage: file.url || file.thumbUrl,
    previewVisible: true,
    });
    } handleImgChange = ({ fileList }) => this.setState({ imgList: fileList }) // 上传文件 使用的方法
    // 删除、预览弹框关闭、预览文件url和预览弹框打开,存储文件的图片url
    handleFileRemove = () => {
    this.setState({
    fileList: [],
    fileUri: [''],
    })
    return true
    } handleFileCancel = () => this.setState({ fileVisible: false }) handleFilePreview = (file) => {
    file.url ?
    this.setState({
    previewFile: file.url,
    fileVisible: true,
    }) :
    message.error('请先保存');
    } handleFileChange = ({ fileList }) => this.setState({ fileList })
  • 弹框表单中上传多张图片

  1. 引入upload.js中封装的handImageUpload文件上传七牛云的方法

    import { handleImageUpload } from '@/utils/upload';
    import {setFileHost} from '@/utils/utils';
  2. state中定义初始数据
    // 上传多张轮播图(可上传视频)
    imgList: [],
    fileThumbs: [],
    previewVisible: false,
    previewImage: '', // 上传一张图片
    introImgList: [],
    introFileThumb: '',
    introPreviewVisible: false,
    introPreviewImage: '',
  3. showModal显示弹框的方法中: 处理获得的图片数组存入state

    showEditModal = item => {
    const { dispatch } = this.props; dispatch({
    type: 'project/fetchDetail',
    payload: {
    goodsId: item.id
    },
    callback: (res) => {
    if(res){
    this.setState({
    detail: res.data,
    imgList: res.data.rotationChart && res.data.rotationChart.length
    ? this.initImgList(res.data) : "", // Upload显示图片本地存储的图片url数组
    fileThumbs: res.data.rotationChart && res.data.rotationChart.length
    ? this.initFileThumbs(res.data) : "", // 上传七牛云后存储的用于传给后端的图片url数组
    introImgList: res.data.introPic
    ? [{
    uid: '-1',
    status: 'done',
    name: res.data.introPic,
    url: `${setFileHost()+res.data.introPic}`,
    thumbUrl: `${setFileHost()+res.data.introPic}`
    }] : '',
    introFileThumb: res.data.introPic ? res.data.introPic : '',
    current: item,
    addSubmit: false
    }, () => {
    this.setState({
    visible: true
    })
    });
    }
    }
    })
    };
  4. 弹框表单中嵌入Upload组件

     const ImgUpButton = (       //  上传图片的按钮
    <div>
    <Icon type="plus" />
    <div className="ant-upload-text">Upload</div>
    </div>
    );
    <FormItem label="产品图片" {...formLayout}>
    { getFieldDecorator('rotationChart', {
    rules: [{ required: true, message: '请上传1-7张图片'}],
    // 默认显示是图片数组,无值也是空数组
    initialValue: current && detail && detail.rotationChart && detail.rotationChart.length
    ? initImgList(detail) : []
    })(
    <div>
    <Upload
    accept="image/*"
    // action={(file) => handleImageUpload(file, 'image').then(res => {
    // handleFileThumb(res, file, imgList)
    // })}
    listType="picture-card"
    fileList={imgList}
    onPreview={handleImgPreview}
    onRemove={handleImgRemove}
    // beforeUpload上传前的处理函数: 嵌套handleImageUpload方法 (上传一张图片或一个文件时,如果需要上传前判断文件类型、文件大小也是这么做)
    // 1.包含handleFileThumb方法,代替action实现上传七牛云服务器后存储state;2.同时将新的图片数组imgArray存入本地imgList改变Upload组件显示的图片
    beforeUpload={beforeUpload}
    // onChange={handleImgChange}
    >
    {imgList.length >= 7 ? null : ImgUpButton}
    </Upload>
    <Modal visible={previewVisible} footer={null} onCancel={handleImgCancel} style={{textAlign: 'center'}}>
    { previewType == 'liveWallPaper' ?
    <video src={previewImage} style={{ width: '50%' }} controls="controls" autoPlay="autoplay">
    您的浏览器不支持 video 标签。
    </video>
    : <img alt="产品图片" style={{ width: '100%' }} src={previewImage} />}
    </Modal>
    </div>
    )}
    </FormItem>
  5. 使用到的方法

    initImgList = (item) => {   // 处理Upload默认显示的数据
    let defaultImgList = [];
    item.rotationChart.forEach((imgListItem, index) => {
    defaultImgList.push ({
    uid: `${-1-index}`,
    status: 'done',
    name: item.name,
    url: imgListItem.img ? `${setFileHost()+imgListItem.img}` : '',
    thumbUrl: imgListItem.thumb ? `${setFileHost()+imgListItem.thumb}` : ''
    })
    })
    return defaultImgList
    }
    initFileThumbs = (item) => {  // 不更改不上传新的图片时默认向后端传的图片url数组
    let defaultFileThumbs = [];
    item.rotationChart.forEach((fileThumb, index) => {
    defaultFileThumbs[index] = fileThumb;
    })
    return defaultFileThumbs
    }
    handleFileThumb = (res, file, imgList) => {  // 更改fileThumbs数组
    let { fileThumbs } = this.state;
    fileThumbs[imgList.length-1] = {
    img: res,
    index: imgList.length-1,
    type: file.type.split('/')[0],
    thumb: res
    };
    this.setState({
    fileThumbs
    })
    }
    // 关闭预览弹框
    handleImgCancel = () => this.setState({ previewVisible: false }) // 显示预览弹框
    handleImgPreview = (file) => {
    this.setState({
    previewImage: file.url || file.thumbUrl,
    previewVisible: true,
    });
    } // 删除预览弹框
    handleImgRemove = (file) => {
    const { fileThumbs, imgList } = this.state;
    let newList = [...imgList];
    let newFileThumbs = [...fileThumbs];
    newList.forEach((imgItem, index) => {
    if(imgItem.uid == file.uid){
    newList.splice(index, 1)
    newFileThumbs.splice(index, 1)
    }
    })
    this.setState({
    imgList: newList,
    fileThumbs: newFileThumbs
    }, () => {
    return true
    })
    }
    beforeUpload = (file) => {
    let type = file.type.split('/')[0];
    let name = file.name.split('.')[0]; // 判断文件类型 -- 如果是视频url直接存入imgList,存入fileThumb
    if(type == 'video') {
    let imgArray = [...this.state.imgList];
    imgArray.push(file); handleImageUpload(file, 'video', name).then(res => {
    this.setState({
    imgList: imgArray
    })
    this.handleFileThumb(res, file, imgArray)
    })
    }else{
    // 如果是图片,使用react-cropper插件相关设置进行裁剪处理
    // 当打开同一张图片的时候清除上一次的缓存
    if (this.refs.cropper) {
    this.refs.cropper.reset();
    } var reader = new FileReader();
    const image = new Image();
    //因为读取文件需要时间,所以要在回调函数中使用读取的结果
    reader.readAsDataURL(file); //开始读取文件 reader.onload = (e) => {
    image.src = reader.result;
    image.onload = () => {
    this.setState({
    srcCropper: e.target.result, //cropper的图片路径
    selectImgName: file.name, //文件名称
    selectImgSize: (file.size / 1024 / 1024), //文件大小
    selectImgSuffix: file.type.split("/")[1], //文件类型
    editImageModalVisible: true, //打开控制裁剪弹窗的变量,为true即弹窗
    })
    if (this.refs.cropper) {
    this.refs.cropper.replace(e.target.result);
    }
    }
    }
    return false;
    }
    }
  • 不需要裁剪的使用beforeUpload判断文件大小的上传一张图片

    <FormItem label="人物介绍图片" {...formLayout}>
    {getFieldDecorator('introPic', {
    initialValue: current && detail && detail.introPic
    ? [{
    uid: '-1',
    status: 'done',
    name: detail.introPic,
    url: `${setFileHost()+detail.introPic}`,
    thumbUrl: `${setFileHost()+detail.introPic}`
    }] : ''
    })(
    <div>
    <Upload
    accept="image/*"
    // action={(file) => handleImageUpload(file, 'image').then(res => {
    // handleIntroFileThumb(res)
    // })}
    listType="picture-card"
    fileList={introImgList}
    onPreview={handleIntroImgPreview}
    onRemove={handleIntroImgRemove}
    beforeUpload={beforeIntroUpload}
    // onChange={handleIntroImgChange}
    >
    {introImgList.length >= 1 ? null : ImgUpButton}
    </Upload>
    <Modal visible={introPreviewVisible} footer={null} onCancel={handleIntroImgCancel} style={{textAlign: 'center'}}>
    <img alt="人物介绍图片" style={{ width: '100%' }} src={introPreviewImage} />
    </Modal>
    </div>
    )}
    </FormItem>
    beforeIntroUpload = (file) => {
    const isLt3M = file.size / 1024 / 1024 < 3;
    if (!isLt3M) { //添加文件限制
    message.error('文件大小不能超过3M');
    return false;
    }
    // console.log('file', file) handleImageUpload(file, 'image').then(res => {
    this.setState({ // 存入introImgList
    introImgList: [{
    uid: file.uid,
    status: 'done',
    name: file.name,
    url: `${setFileHost()+res}`,
    thumbUrl: `${setFileHost()+res}`
    }]
    })
    this.handleIntroFileThumb(res) // 存入introFileThumbs
    }) return true
    }

转载请注明出处

【后台管理系统】—— Ant Design Pro组件使用(一)的更多相关文章

  1. 【后台管理系统】—— Ant Design Pro组件使用(二)

    一.关联表单项 - 动态增删输入框Input        封装子组件 class ParamsInputArray extends React.Component{ constructor(prop ...

  2. Ant Design Pro路由传值

    Ant Design Pro 路由传值 了解Ant Design Pro组件间通讯原理的小伙伴肯定都知道,两个页面之间可以通过Models进行传值,在以往的传值过程中,我都是直接将需要的值直接一股脑的 ...

  3. 【后台管理系统】—— Ant Design Pro入门学习&项目实践笔记(三)

    前言:前一篇记录了[后台管理系统]目前进展开发中遇到的一些应用点,这一篇会梳理一些自己学习Ant Design Pro源码的功能点.附:Ant Design Pro 在线预览地址. Dashboard ...

  4. Ant Design Pro (中后台系统)教程

    一.概念:https://pro.ant.design/docs/getting-started-cn(官方网站) 1.Ant Design Pro 是什么:  https://www.cnblogs ...

  5. ant design pro 当中改变ant design 组件的样式和 数据管理

    ant design pro 简介 官网简介 链接 https://pro.ant.design/docs/getting-started-cn 项目结构 https://github.com/ant ...

  6. Ant Design Pro 学习笔记:数据流向

    在讲这个问题之前,有一个问题应当讲一下: Ant Design Pro / umi / dva 是什么关系? 首先是 umi / dva 的关系. umi 是一个基于路由的 react 开发框架. d ...

  7. 阿里开源项目之Ant Design Pro

    本篇文章主要包含的内容有三个方面. 第一.Ant Design Pro简介; 第二.Ant Design Pro能做什么; 第三.初步使用; 我相信通过这三个方面的讲解能让你大概知道Ant Desig ...

  8. ant design pro(一)安装、目录结构、项目加载启动【原始、以及idea开发】

    一.概述 1.1.脚手架概念 编程领域中的“脚手架(Scaffolding)”指的是能够快速搭建项目“骨架”的一类工具.例如大多数的React项目都有src,public,webpack配置文件等等, ...

  9. Ant Design Pro快速入门

    在上一篇文章中,我们介绍了如何构建一个Ant Design Pro的环境. 同时讲解了如何启动服务并查看前端页面功能. 在本文中,我们将简单讲解如何在Ant Design Pro框架下实现自己的业务功 ...

随机推荐

  1. hdu1263 简单模拟

    题意:依据水果销量表.依照特定格式输出 格式:首先按产地排序,然后同一产地按水果名排序 注意:第一,设计多级排序           第二.同一产地同一水果可能多次出现,所以须要在前面已经输入的水果里 ...

  2. 【C#】获取"我的电脑"的名字,如This PC、这台计算机

    原文:[C#]获取"我的电脑"的名字,如This PC.这台计算机 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接: ...

  3. 01.AutoMapper 之约定(Conventions)

    转载(https://www.jianshu.com/p/d4c472d95da4)   约定(Conventions) 条件对象映射器 条件对象映射器根据源类型和目标类型之间的条件生成新类型映射. ...

  4. j网络爬虫之WebMagic

    WebMagic官网:http://webmagic.io/ 注意: 1.在自定义PageProcessor中使用System.out.println(“str”),Spider.create(new ...

  5. 解决PKIX path building failed的问题

    Java在请求某些不受信任的https网站时会报:PKIX path building failed 解决方法一:使用keytool手动导入证书,为JRE环境导入信任证书 参考:http://www. ...

  6. 关于JSON.parse(JSON.stringify(obj))实现深拷贝应该注意的坑

    JSON.parse(JSON.stringify(obj))我们一般用来深拷贝,其过程说白了 就是利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反 ...

  7. (架构)React Native 导出项目全局共用组件的模块

    自定义组件全局使用(类似如下) import { ReactNavComponent, Widget, Util } from 'rn-yunxi'; const { RegexpUtil, Stor ...

  8. Spring基础17——使用注解来配置Bean

    1.组件扫描 组件扫描(component scanning):Spring能够从classpath下自动扫描,侦测和实例化具有特定的注解的组件. 特定组件包括: —@Component:基本注解,标 ...

  9. alex说:一切皆bytes

    一.ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有英文,而单字节可以表示25 ...

  10. PAT Advanced 1006 Sign In and Sign Out (25 分)

    At the beginning of every day, the first person who signs in the computer room will unlock the door, ...