Java从零单排 -- 小马哥商城实战(4)

166 阅读3分钟

前言

在前面的章节,我们弄好了商城的基础后台,然我们的商家举报商品上架,库存增减的功能,那么这章节我们将开始做用户前台功能。

用户前台功能:

  • 用户登陆
  • 充值
  • 查看商品列表
  • 将商品添加到购物车
  • 结账

用户登陆

  • 系统中无此用户时,创建用户以及初始化一个虚拟钱包。
  • 系统中有此用户时,返回用户信息。 前端设计登陆页面时,只需要根据用户的名称,手机号码就能进行登陆操作了。

前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>前台</title>
</head>
<body>
<div id="app">
   <div>
       <h4>会员注册/登陆</h4>
       <div v-if="loginStatus">
           <div><label>名称:</label><input name="name" v-model="member.name" /></div>
           <div><label>手机号码:</label><input name="mobile" v-model="member.mobile" /></div>
           <button  @click="login">登陆/注册</button>
       </div>
   </div>
</div>



<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.1/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js"></script>
<script>
    new Vue({
            el:'#app',
            data(){
                return{
                   loginStatus:true,
                   member:{
                    name:'',
                    mobile:'',
                    address:'',
                    money:0
                   },
                   list:[]
                }
            },
            created(){
                this.getGoodLists()
            },
            methods:{
                login(){
                    axios.post('member/login',this.member).then(res=>{
                        this.loginStatus = false

                        this.member.name = res.data.name;
                        this.member.mobile = res.data.mobile;
                        this.member.money = res.data.money;
                        this.member.id = res.data.id
                    })
                },
            }

    })
</script>
</body>
</html>

java 代码编写login接口

@RestController
@RequestMapping("member")
public class MemberController {

    @Autowired
    private MemberService memberService;

    @PostMapping("login")
    public JSONObject addMember(@RequestBody JSONObject requestJson){
        return memberService.addMember(requestJson);
    }
}

按上述条件描述,编写会员登陆逻辑;

@Service
public class MemberServiceImpl implements MemberService {
    @Autowired
    private MemberDao memberDao;
    @Autowired
    private WalletDao walletDao;

    @Transactional
    @Override
    public JSONObject addMember(JSONObject requestJson) {

        //将json中字段转换为member 实体
        Member member = JSONObject.toJavaObject(requestJson, Member.class);

        //查询会员
        JSONObject existMember = memberDao.getMemberByMobile(member);
        if (existMember == null) {
            //创建会员
            member.setCreateTime(new Date());
            member.setAddress("");
            member.setCreateUser(1);
            member.setSex(0);
            member.setCreateUser(1);
            memberDao.addMember(member);

            //创建钱包
            Wallet wallet = new Wallet();
            wallet.setMemberId(member.getId());
            wallet.setCreateTime(new Date());
            wallet.setStatus(0);
            wallet.setCreateUser(1);
            wallet.setMoney(new BigDecimal(0));
            walletDao.addWallet(wallet);

            JSONObject memberDto = new JSONObject();
            memberDto.put("id",member.getId());
            memberDto.put("name",member.getName());
            memberDto.put("mobile",member.getMobile());
            memberDto.put("money",0);

        }
        return existMember;

    }
}

sql 插入完数据后,要求返回数据的自增id,可以通过mybatis的selectKey功能,keyProperty="id" 为返回的自增id

 <insert id="addMember" >
        <selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
            SELECT LAST_INSERT_ID()
        </selectKey>
        insert into member(name,sex,address,mobile,create_time,status,create_user)
        values (#{name},#{sex},#{address},#{mobile},#{createTime},#{status},#{createUser})
    </insert>
    <select id="getMemberByMobile" resultType="com.alibaba.fastjson.JSONObject">
        select
        m.id,
        m.name,
        m.mobile,
        w.money
        from member m
        left join wallet w on m.id = w.member_id
        where mobile = #{mobile}
    </select>

登陆之后,要查看到用户的具体信息:名称、手机号码、钱包余额,查看都商品列表;具体登陆结果。

加入购物车

新设计一张购物车表,用来记录添加的商品。

CREATE TABLE `shopping_car` (
  `id` int NOT NULL AUTO_INCREMENT,
  `good_id` int DEFAULT NULL,
  `amount` int DEFAULT NULL,
  `member_id` int DEFAULT NULL,
  `status` tinyint DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `create_user` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

前端点击加入购物车按钮,点一次增加一件。

前端代码

 <div v-for="item in list" style="border:solid;margin:2px;padding:5px">
                   <p>商品名称:{{item.name}}</p>
                   <p>商品描述:{{item.remark}}</p>
                   <p>商品价格:{{item.price}}</p>
                   <p>商品数量:{{item.amount||0}} <button @click="addShoppingCar(item.id)">加入购物车</button></p>
                   <image v-if="item.image" :src="'good/getGoodImg/'+item.image" style="width:50px;height:50px"/>
               </div>
               
                addShoppingCar(id){
                    axios.post('shoppingCar/add',{goodId:id,memberId:this.member.id}).then(res=>{
                    })
                }

shoppingCar/add接口,service逻辑为

@Service
public class ShoppingCarImpl implements ShoppingCarService {

    @Autowired
    private WarehouseDao warehouseDao;
    @Autowired
    private ShoppingCarDao shoppingCarDao;

    @Transactional
    @Override
    public String addShoppingCar(JSONObject requestJson) {
        int goodId = requestJson.getIntValue("goodId");
        int memberId = requestJson.getIntValue("memberId");
        //先判断是否有库存
        Warehouse warehouse = warehouseDao.getWarehouseByGoodId(goodId);
        if (warehouse != null) {
            //库存数量大于0才能添加
            if (warehouse.getAmount() > 0) {
                ShoppingCar shoppingCar = new ShoppingCar();
                shoppingCar.setMemberId(memberId);
                shoppingCar.setGoodId(goodId);
                ShoppingCar existCar = shoppingCarDao.getCar(shoppingCar);
                //购物车插入一条数据
                if (existCar == null) {
                    shoppingCar.setAmount(1);
                    shoppingCar.setCreateTime(new Date());
                    shoppingCar.setCreateUser(1);
                    shoppingCar.setStatus(0);
                    shoppingCarDao.add(shoppingCar);
                } else {
                    //更新购物车信息
                    shoppingCarDao.update(existCar);
                }
                return "ok";
            }
        }
        return "error";
    }
}

sql,sql可以运用四则运算的,试下点击一次商品,购物车数量增加一件。

    <insert id="add">
        insert into shopping_car(good_id,member_id,amount,status,create_time,create_user)
        values(#{goodId},#{memberId},#{amount},#{status},#{createTime},#{createUser})
    </insert>
    <update id="update">
        update shopping_car set amount=amount+1
        where
        member_id = #{memberId}
        and good_id=#{goodId}
        and status = 0
        and amount = #{amount}
    </update>
    <select id="getCar" resultType="com.xiaoma.mall.entity.ShoppingCar">
        select id,
        good_id goodId,
        member_id memberId,
        amount
        from shopping_car
        where
        member_id = #{memberId}
        and good_id=#{goodId}
        and status = 0

    </select>

查看购物车

当用户登陆的时候,需要查看到购物车的信息,添加商品也需要查看购物车信息,那么前端代码就成。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>前台</title>
</head>
<body>
<div id="app">
   <div>
       <h4>会员注册/登陆</h4>
       <div v-if="loginStatus">
           <div><label>名称:</label><input name="name" v-model="member.name" /></div>
           <div><label>手机号码:</label><input name="mobile" v-model="member.mobile" /></div>
           <button  @click="login">登陆/注册</button>
       </div>
       <div  v-if="!loginStatus">
           <div><label>名称:</label>{{member.name}} <label>  手机号码:</label>{{member.mobile}}<label>  钱包余额:</label>{{member.money}}</div>
       </div>

       <div style="display:flex;flex-wrap: wrap;margin-top:100px">
           <div v-for="item in list" style="border:solid;margin:2px;padding:5px">
               <p>商品名称:{{item.name}}</p>
               <p>商品描述:{{item.remark}}</p>
               <p>商品价格:{{item.price}}</p>
               <p>商品数量:{{item.amount||0}} <button @click="addShoppingCar(item.id)">加入购物车</button></p>
               <image v-if="item.image" :src="'good/getGoodImg/'+item.image" style="width:50px;height:50px"/>
           </div>
       </div>
       <div  v-if="!loginStatus">
           <table title="购物车" border="1">
               <tr><th>商品名称</th><th>数量</th><th>价格</th></tr>
               <tr v-for="item in shoppingCarList"><td>{{item.name}}</td><td>{{item.amount}}</td><td>{{item.price}}</td></tr>
           </table>
       </div>
   </div>
</div>



<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.1/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js"></script>
<script>
    new Vue({
            el:'#app',
            data(){
                return{
                   loginStatus:true,
                   member:{
                    id:'',
                    name:'',
                    mobile:'',
                    address:'',
                    money:0
                   },
                   list:[],
                   shoppingCarList:[]
                }
            },
            created(){
                this.getGoodLists()
            },
            methods:{
                login(){
                    axios.post('member/login',this.member).then(res=>{
                        this.loginStatus = false

                        this.member.name = res.data.name;
                        this.member.mobile = res.data.mobile;
                        this.member.money = res.data.money;
                        this.member.id = res.data.id
                        this.getShoppingCar()
                    })
                },
                getGoodLists(){
                  axios.get('good/getList').then(response => {this.list = response.data;})
                },
                addShoppingCar(id){
                    axios.post('shoppingCar/add',{goodId:id,memberId:this.member.id}).then(res=>{
                     this.getShoppingCar()
                    })
                },
                getShoppingCar(){
                     axios.get('shoppingCar/getList?memberId='+this.member.id).then(response => {this.shoppingCarList = response.data})
                }
            }

    })
</script>
</body>
</html>

数据接口查询逻辑为

 <select id="getList" resultType="com.alibaba.fastjson.JSONObject">
        SELECT
            sc.id,
            sc.good_id goodId,
            sc.member_id memberId,
            sc.amount,
            g.name,
            g.price * sc.amount price
        FROM
        shopping_car sc LEFT JOIN good g on sc.good_id = g.id
        WHERE
        sc.member_id = #{memberId}
        AND sc.STATUS = 0
    </select>

小结

这章节,我为大家描述了一个简单的用户注册,添加购物车的场景,大致为1.用户注册,查看购物车;2.在商品列表选择商品添加购物车;3.刷新购物车。我们学习的就是需要更加场景合理的编写我们的代码,设计我们的数据。