首页 > 其他分享 >react图书商城前后端

react图书商城前后端

时间:2023-08-01 10:47:18浏览次数:25  
标签:axios value react item 商城 import data id 图书

下载:axios antd-mobile antd-mobile-icons sass

连接mongodb:

const mongoose = require("mongoose")
mongoose.connect('mongodb://127.0.0.1:27017/zg5_zk3_2204_express',(err)=>{
    if(!err){
        console.log('连接成功!');
    }
})
module.exports=mongoose

创建表模型:

const mongoose = require("./db")
var Schema = mongoose.Schema
 
// 图书
var bookSchema = new Schema({
    bookName:String,
    img:String,
    // 判断是否在书架里: false没在书架,true在书架
    state:{
        type:Boolean,
        default:false
    },
    // 判断是否看完:false正在看,true已完结
    bookState:{
        type:Boolean,
        default:false
    }
})
var bookModel = mongoose.model("Book",bookSchema)
 
// 用户
var userSchema = new Schema({
    mobile:String,
    passWord:String
})
var userModel = mongoose.model("User",userSchema)
 
module.exports = { bookModel,userModel }

后端接口:

// 登录时添加用户
router.post("/user/add",async (req,res)=>{
  var data = req.body
  await userModel.create(data)
  res.send({
    token:data.mobile
  })
})
 
 
// shop路由及book路由图书展示
router.get("/book/list",async (req,res)=>{
  var data
  if(!req.query.search){
    data =  await bookModel.find()
  }else{
    data =  await bookModel.find({bookName:req.query.search})
 
  }
  res.send({
    data
  })
})
 
// shop路由的图书添加
router.post("/book/add",async (req,res)=>{
  let data = req.body._id
  await bookModel.updateOne({_id:data},{state:true})
  res.send({})
 
})
 
// bookState状态的更改
router.post("/bookState/update",async (req,res)=>{
  let data = req.body
  await bookModel.updateOne({_id:data._id},{bookState:data.bookState})
  res.send({})
})
 
// state状态的更改
router.post("/state/update",async (req,res)=>{
  let data = req.body
  await bookModel.updateOne({_id:data._id},{state:false})
  res.send({})
})

前端登录页面:

import React, { useState } from 'react'
import { Form, Input, Button } from 'antd-mobile'
import styles from './demo2.less'
import { CloseOutline, CheckOutline } from 'antd-mobile-icons'
import { history } from 'umi'
import axios from 'axios'
 
export default function Login() {
    /** 切换主题 */
 
    // 存储颜色列表
    const back = ["black","red", "blue", "green"]
    const [backIndex, setBackIndex] = useState(0)
    // 切换主题
    let backClick = () => {
        let backindex = backIndex
        if (backindex >= back.length - 1) {
            setBackIndex(0)
        } else {
            backindex += 1
            setBackIndex(backindex)
        }
    }
    /** 手机号 */
 
    // 存储手机号,用于校验
    const [mobile, setMobile] = useState("")
    // 手机号的change事件
    let onMobileChange = (value) => {
        setMobile(value)
    }
    // 手机号的校验
    const phone = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
 
    /** 密码 */
 
    // 存储密码,用于校验
    const [passWord, setPassWord] = useState("")
    // 密码的change事件
    let onPassWordChange = (value: any) => {
        setPassWord(value)
    }
    // 密码的校验
    const pwd = /^[a-zA-Z][a-zA-Z0-9]{5}$/
 
    /** 点击登录 */
    let onLoginClick = () => {
        axios.post("http://localhost:3000/user/add", { mobile: mobile, passWord: passWord }).then(value => {
            window.localStorage.setItem("token", value.data.token)
            history.push({ pathname: "/shop" })
        })
    }
    return (
        <div>
            <h1 style={{ height: "60px", width: "100%", color: "white", textAlign: "center", fontSize: "24px", lineHeight: "60px", backgroundColor: back[backIndex] }}>用户登录 <b onClick={backClick} style={{ fontSize: "12px", float: "right", lineHeight: "60px", color: "white" }}>切换主题</b> </h1>
            <div>
                <Form style={{ marginTop: "150px" }} layout='horizontal'>
                    <Form.Item
                        label='手机号码'
                        extra={
                            <div className={styles.extraPart}>
                                {phone.test(mobile) ? <CheckOutline style={{ background: "green", border: "none", borderRadius: "50%", color: "white" }} /> : <CloseOutline style={{ background: "red", border: "none", borderRadius: "50%", color: "white" }} />}
                            </div>
                        }
                    >
                        <Input onChange={onMobileChange} placeholder='请输入手机号码' clearable />
                    </Form.Item>
                    <Form.Item
                        label='密码'
                        extra={
                            <div className={styles.extraPart}>
                                {pwd.test(passWord) ? <CheckOutline style={{ background: "green", border: "none", borderRadius: "50%", color: "white" }} /> : <CloseOutline style={{ background: "red", border: "none", borderRadius: "50%", color: "white" }} />}
                            </div>
                        }
                    >
                        <Input onChange={onPassWordChange} placeholder='请输入密码' clearable />
                    </Form.Item>
                    <Button onClick={onLoginClick} disabled={pwd.test(passWord) && phone.test(mobile) ? false : true} style={{ border: "none", background: back[backIndex], marginTop: "50px" }} block type='submit' color='primary' size='large'>
                        登录
                    </Button>
                </Form>
 
            </div>
 
 
        </div>
    )
}

css样式:scss格式

.extraPart {
    border-left: solid 1px #eeeeee;
    padding-left: 12px;
    font-size: 17px;
    line-height: 22px;
  }
  .eye {
    padding: 4px;
    cursor: pointer;
    svg {
      display: block;
      font-size: var(--adm-font-size-7);
    }
  }

图书商城:

import React, { useEffect, useState } from 'react'
import { Input,Toast  } from 'antd-mobile'
import { CloseOutline, CheckOutline,AddOutline } from 'antd-mobile-icons'
import axios from 'axios'
import { history } from 'umi'
export default function Shop() {
    const [inputValue,setInputValue] = useState("")
    const [data,setData] = useState([])
    let getBookList = (value:any) =>{
        axios.get("http://localhost:3000/book/list?search="+value).then(value=>{
            setData(value.data.data);
        })
    }
    let onInputChange = (value:any) =>{
        setInputValue(value)
        getBookList(value)
    }
    // 添加图书到书架
    let addBook = (item:any) =>{
        if(item.state){
            Toast.show({
                content: '书架中已有此书',
                duration: 1000,
              })
        }else{
            axios.post("http://localhost:3000/book/add",{_id:item._id}).then(value=>{
                getBookList(inputValue)
                Toast.show({
                    content: '加入成功',
                    duration: 1000,
                  })
            })
        }
        
    }
 
    useEffect(()=>{
        getBookList(inputValue)
    },[])
    return (
        <div>
            <h1  style={{ position:"sticky",top:"0",left:"0", height: "60px", width: "100%", color: "white", textAlign: "center", fontSize: "24px", lineHeight: "60px", backgroundColor: "red" }}>图书商城 <b onClick={() => { history.push({pathname:"/book"}) }} style={{ fontSize: "12px", float: "right", lineHeight: "60px", color: "white" }}>我的书架</b> </h1>
            <div>
                <Input onChange={onInputChange} style={{ border:"1px solid red",marginTop:"-5px" }} placeholder='请输入书名搜索' />
                <div>
                    {
                        data.map((item, index) => {
                            return (<div key={item.bookName} style={{ marginBottom:"5px",border:"1px solid black", float: index%2==0 ? "left":"right",  width: "45%", display: "inline-block" }}>
                                <img style={{ marginBottom:"15px",height:"200px",width: "100%" }} src={require("../images/" + item.img)} alt="" />
                                <p style={{ color:'red' }}>{item.bookName} <AddOutline onClick={()=>{addBook(item)}} style={{ float:"right",marginRight:"10px", color:"white",backgroundColor:"red",border:"none",borderRadius:"50%" }} /></p>
                            </div>)
                        })
                    }
                </div>
            </div>
        </div>
    )
}

书架:

import React, { useState, useEffect } from 'react'
import { NavBar, Collapse } from 'antd-mobile'
import axios from 'axios'
import { history } from 'umi'
 
export default function Book() {
    const [data, setData] = useState([])
    const back = () => {
        history.push({pathname:"/shop"})
    }
 
    useEffect(() => {
        axios.get("http://localhost:3000/book/list").then(value => {
            setData(value.data.data);
        })
    }, [])
 
    let onLeftClick = (id, state) => {
        axios.post("http://localhost:3000/bookState/update", { _id: id, bookState: state }).then(value => {
            axios.get("http://localhost:3000/book/list").then(value => {
                setData(value.data.data);
            })
        })
    }
    let onRightClick = (id) => {
        axios.post("http://localhost:3000/state/update", { _id: id }).then(value => {
            axios.get("http://localhost:3000/book/list").then(value => {
                setData(value.data.data);
            })
        })
    }
    return (
        <div>
            <NavBar style={{ color: "white", textAlign: "center", fontSize: "24px", lineHeight: "60px", backgroundColor: "red" }} onBack={back}>图书商城 </NavBar>
            <div>
                <Collapse>
                    <Collapse.Panel key='1' title='正在看'>
                        <ul style={{ listStyle: "none" }}>
                            {
                                data.filter(item => { return !item.bookState && item.state }).length >0?
                                data.filter(item => { return !item.bookState && item.state }).map(item => {
                                    return (
                                        <li key={item.bookName} style={{ marginBottom: "7px" }}>
                                            <b style={{ color: "black" }}>{item.bookName}</b>
                                            <div style={{ float: "right" }}>
                                                <span onClick={() => { onLeftClick(item._id, true) }} style={{ color: "red" }}>标记为已看完  |</span>
                                                <span onClick={() => { onRightClick(item._id) }}>  删除图书</span>
                                            </div>
                                        </li>
                                    )
                                }): <li>没有正在看的图书</li>
                            }
                        </ul>
                    </Collapse.Panel>
                    <Collapse.Panel key='2' title='已完结'>
                        <ul style={{ listStyle: "none" }}>
                            {   data.filter(item => { return item.bookState && item.state }).length >0?
                                data.filter(item => { return item.bookState && item.state }).map(item => {
                                    return (
                                        <li key={item.bookName} style={{ marginBottom: "7px" }}>
                                            <b style={{ color: "black" }}>{item.bookName}</b>
                                            <div style={{ float: "right" }}>
                                                <span onClick={() => { onLeftClick(item._id, false) }} style={{ color: "red" }}>再看一遍  |</span>
                                                <span onClick={() => { onRightClick(item._id) }}>  删除图书</span>
                                            </div>
                                        </li>
                                    )
                                }): <li>没有看完的图书</li>
                            }
                        </ul>
                    </Collapse.Panel>
                </Collapse>
            </div>
        </div>
    )
}

 

标签:axios,value,react,item,商城,import,data,id,图书
From: https://www.cnblogs.com/wananyy/p/17595825.html

相关文章

  • react路由6登录拦截
    自定义登录拦截组件://路由守卫//判断token是否存在,如果存在跳转页面,不存在返回登录页面import{Navigate}from'react-router-dom'constgetToken=()=>{returnsessionStorage.getItem("token")}functionAuthRouter({children}){//获取token......
  • react使用自定义animation实现水平效果的路由切换
    例如:A组件跳B组件 A组件:importReactfrom'react';import'./A.scss'import{useNavigate}from'react-router-dom';exportdefaultfunctionA(){letnavigate=useNavigate()return(<divonClick={()=>{l......
  • react简历案例--前后端
    express:下载 mongoose 7版本+配置cors1:创建module文件夹(db.js、module.js)连接mongodb数据库:constmongoose=require("mongoose")mongoose.connect("mongodb://127.0.0.1:27017/zg6_zk3_2204_koa").then(()=>{console.log("连接成功");})mod......
  • [回馈]ASP.NET Core MVC开发实战之商城系统(四)
    经过一段时间的准备,新的一期【ASP.NETCoreMVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面等功能的开发,今天继续讲解商品详情功能开发,仅供学习分享使......
  • 微商城小程序怎么开发?(微商城小程序开发流程)
    微商城小程序作为一个便捷的电商平台,成为越来越多企业和个人的选择。它不仅为商家提供了一个在线销售的渠道,也为消费者提供了更方便快捷的购物体验。那么,如何开发一个成功的微商城小程序呢?接下来广州名锐讯动将介绍微商城小程序的开发流程,并分享一些关键步骤和注意事项。第一步:需求......
  • 浅聊一下,React会不会被VUE取代?
    看到知乎上有比较多的类似问题,正好这两个框架在以往的一些项目中都有实践过,就借着本篇文章说说我个人的看法。 先摆个结论:不会,毕竟各有千秋,除非跨端框架有被更好的概念所替代,又或者App已经彻底过气了。 什么是React?什么是VUE?维基百科上的概念解释,Vue.js是一个用于创......
  • 谷粒商城项目篇7_分布式高级篇_全文检索ES、商城业务(商品上架)、Feign源码简析
    目录全文检索ESES入门概念Docker安装ES基本操作举栗查询QueryDSL聚合aggregations映射Mapping安装ik分词器安装Nginx,配置远程词库整合SpringBoot新建微服务模块,导入依赖配置使用测试项目中使用场景商城业务商品上架ES的Mapping设计上架代码编写Feign源码封装消息返回R细节问题一、......
  • reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.IndexOutOfBoundsE
    生产环境好好的,突然前端请求全部跨域,请求500。gateway报错。reactor.core.Exceptions$ErrorCallbackNotImplemented:java.lang.IndexOutOfBoundsException:Index:0,Size:0。所有的接口都报。原因由于gateway也集成了springboot-admin,开启了应用程序的actuator端点,导致......
  • react18 hooks自定义移动端Popup弹窗组件RcPop
    基于React18Hooks实现手机端弹框组件RcPopreact-popup基于react18+hook自定义多功能弹框组件。整合了msg/alert/dialog/toast及android/ios弹窗效果。支持20+自定义参数、组件式+函数式调用方式,全方位满足各种弹窗场景需求。引入组件在需要使用弹窗的页面引入组件。//引......
  • React重新渲染的触发机制及其优化策略
    React是一个用于构建用户界面的JavaScript库,它的核心特点之一是使用虚拟DOM(VirtualDOM)来实现高效的组件渲染。那组件重新渲染的机制是如何呢?基于这些机制,如果进行优化呢?虚拟DOM是一个用JavaScript对象表示的DOM树,它可以在内存中快速地创建和修改,而不需要直接操作真实的DOM。React......