feat 添加订单管理接口

This commit is contained in:
LittleBoy 2022-12-09 15:12:58 +08:00
parent f82d972038
commit 403afa9ba8
18 changed files with 181 additions and 40 deletions

View File

@ -50,7 +50,8 @@
--border-radius-middle: calc(var(--border-radius) + 2px); --border-radius-middle: calc(var(--border-radius) + 2px);
--border-radius-large: calc(var(--border-radius) + 3px); --border-radius-large: calc(var(--border-radius) + 3px);
--header-height: 80px; --header-bg: #001529;
--header-height: 50px;
--left-menu-width: 200px; --left-menu-width: 200px;
} }
@ -130,29 +131,38 @@ body {
} }
table { table {
width: 100%; width: 100%;
border-left: solid 1px #eee; border: solid 1px #eee;
border-top: solid 1px #eee;
border-collapse: collapse; border-collapse: collapse;
font-size: 13px;
}
th{
background-color: #f5f7fa;
} }
td, th { td, th {
border-right: solid 1px #eee; text-align: left;
border-bottom: solid 1px #eee; border-bottom: solid 1px #eee;
padding: 6px; padding: 6px 8px;
}
tr{
&:hover{
background-color: #f5f7fa;
}
} }
} }
.page-wrapper { .page-wrapper {
margin: 20px 0; margin: 20px 0;
font-size: 12px;
text-align: right;
.page-item { .page-item {
cursor: pointer; cursor: pointer;
border: solid 1px var(--primary-2); border: solid 1px var(--primary-2);
border-radius: var(--border-radius-middle); border-radius: var(--border-radius-middle);
display: inline-block; display: inline-block;
padding: 4px 10px; padding: 4px 6px;
margin: 0 5px; margin: 0 5px;
min-width: 40px; min-width: 26px;
text-align: center; text-align: center;
&:hover, &.current-page { &:hover, &.current-page {

View File

@ -73,8 +73,8 @@ const btnType = computed(() => props.type || 'primary')
} }
&.btn-link { &.btn-link {
padding:2px;
background: none; background: none;
text-decoration: underline;
color: var(--primary-color) color: var(--primary-color)
} }
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="page-wrapper"> <div class="page-wrapper">
<span v-if="showRefresh" class="refresh" @click="$emit('refresh')">刷新</span> <span v-if="showRefresh" class="page-item refresh" @click="$emit('refresh')">刷新</span>
<span v-if="page > 1" class="prev-page page-item" @click="$emit('page-change',--page)">上一页</span> <span v-if="page > 1" class="prev-page page-item" @click="$emit('page-change',--page)">上一页</span>
<span class="page-item page-first" :class="{'current-page':page == 1}" <span class="page-item page-first" :class="{'current-page':page == 1}"
@click="$emit('page-change',(page=1))">1</span> @click="$emit('page-change',(page=1))">1</span>

View File

@ -61,6 +61,7 @@ export default defineComponent({
const arr = [].slice.call (target.parentElement.children) const arr = [].slice.call (target.parentElement.children)
arr.forEach(ele => (ele as HTMLElement).classList.remove("selected")) arr.forEach(ele => (ele as HTMLElement).classList.remove("selected"))
target.classList.add("selected") target.classList.add("selected")
console.log(target.data)
ctx.emit(UPDATE_MODEL_EVENT,target.data) ctx.emit(UPDATE_MODEL_EVENT,target.data)
onClose() onClose()
} }
@ -79,6 +80,7 @@ export default defineComponent({
<style lang="less"> <style lang="less">
.select-wrapper { .select-wrapper {
position: relative; position: relative;
display: inline-block;
&.active { &.active {
.select-options-wrapper { .select-options-wrapper {
@ -143,6 +145,7 @@ export default defineComponent({
li { li {
line-height: 30px; line-height: 30px;
padding: 0 10px; padding: 0 10px;
cursor: pointer;
&:hover { &:hover {
background-color: #efefef; background-color: #efefef;

View File

@ -6,17 +6,14 @@
<span>标题<PInput style="width:200px" v-model="param.title" placeholder="要查询的商品标题"/></span> <span>标题<PInput style="width:200px" v-model="param.title" placeholder="要查询的商品标题"/></span>
<span> <span>
分类 分类
<select v-model="param.category"> <PSelect v-model="param.category">
<option v-for="(text,value) in CategoryEnum" :key="value" :value="value">{{ text }}</option> <POption v-for="(text,value) in CategoryEnum" :key="value" :value="value">{{text}}</POption>
</select>
<PSelect>
<POption v-for="op in options" :key="op.value">{{op.label}}</POption>
</PSelect> </PSelect>
</span> </span>
<span> <span>
<PButton type="default" @click="onReset">重置</PButton> <PButton type="default" @click="onReset">重置</PButton>
</span> </span>
<span><PButton :disabled="true" :loading="searching" @click="onSearch">搜索</PButton></span> <span><PButton :loading="searching" @click="onSearch">搜索</PButton></span>
</div> </div>
<div class="toolbar-extra"> <div class="toolbar-extra">
<PButton @click="onEditData({id:0})">新增</PButton> <PButton @click="onEditData({id:0})">新增</PButton>
@ -52,9 +49,9 @@
<td>{{ it.offlineTime }}</td> <td>{{ it.offlineTime }}</td>
<td>{{ StatusEnum[it.status] || '未知' }}</td> <td>{{ StatusEnum[it.status] || '未知' }}</td>
<td> <td>
<span @click="onEditData(it)">编辑</span> <PButton type="link" @click="onEditData(it)">编辑</PButton>
<span>禁用</span> <PButton type="link">禁用</PButton>
<span @click="removeData(it.id)">删除</span> <PButton type="link" @click="removeData(it.id)">删除</PButton>
</td> </td>
</tr> </tr>
</table> </table>

View File

@ -13,7 +13,10 @@
<div class="left-menu"> <div class="left-menu">
<div class="title">积分管理系统</div> <div class="title">积分管理系统</div>
<div class="menu-list"> <div class="menu-list">
<router-link v-for="r in AdminRoutes" active-class="active-menu" :to="'/' + r.path">{{ r.meta.title }}</router-link> <router-link v-for="r in AdminRoutes" active-class="active-menu" :to="'/' + r.path">{{
r.meta.title
}}
</router-link>
</div> </div>
</div> </div>
<div class="content-wrapper"> <div class="content-wrapper">
@ -39,13 +42,14 @@ function logout() {
} }
</script> </script>
<style lang="less"> <style lang="less">
.app-admin-layout { .app-admin-layout {
min-height: 100vh; min-height: 100vh;
background-color: #eee; background-color: #eee;
} }
.header { .header {
background-color: var(--primary-color); background-color: var(--header-bg);
color: white; color: white;
line-height: var(--header-height); line-height: var(--header-height);
padding: 0 20px; padding: 0 20px;
@ -55,6 +59,7 @@ function logout() {
left: 0; left: 0;
right: 0; right: 0;
top: 0; top: 0;
z-index: 9;
} }
.main { .main {
@ -63,20 +68,23 @@ function logout() {
.left-menu { .left-menu {
width: 200px; width: 200px;
background-color: black; background-color: #fff;
color: white; color:#333;
box-shadow: 0 2px 3px rgba(0,0,0,0.4);
position: fixed; position: fixed;
left: 0; left: 0;
top: 0; top: 0;
bottom: 0; bottom: 0;
z-index: 10;
font-size: 14px;
} }
.title { .title {
height: var(--header-height); height: var(--header-height);
background-color: #333; background-color: var(--header-bg);
line-height: var(--header-height); line-height: var(--header-height);
text-align: center; text-align: center;
color:white;
font-size: var(--font-size-large); font-size: var(--font-size-large);
} }
@ -86,12 +94,12 @@ function logout() {
a { a {
display: block; display: block;
text-decoration: none; text-decoration: none;
color: white;
padding: 10px 20px; padding: 10px 20px;
color:#333;
&.active-menu { &.active-menu {
background-color: #666666; background-color: var(--primary-1);
color: white; color: var(--primary-color);
} }
} }
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<div> <div class="table-wrapper">
<table> <table>
<tr> <tr>
<th>UID</th> <th>UID</th>

View File

@ -0,0 +1,54 @@
package me.xiaoyan.point.api.controller.admin;
import me.xiaoyan.point.api.error.BizException;
import me.xiaoyan.point.api.pojo.OrderInfo;
import me.xiaoyan.point.api.pojo.vo.OrderQueryParam;
import me.xiaoyan.point.api.pojo.vo.PageDataResult;
import me.xiaoyan.point.api.service.OrderInfoService;
import me.xiaoyan.point.api.util.DataStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
public class OrderAdminController {
@Resource
private OrderInfoService orderInfoService;
@PostMapping("/list")
public PageDataResult list(@RequestBody OrderQueryParam param) {
return PageDataResult.convert(orderInfoService.queryByPage(param));
}
// 修改
@PutMapping("/{id}")
public OrderInfo update(@RequestBody OrderInfo info, @PathVariable("id") String id) {
info.setId(id);
if (!orderInfoService.updateById(info)) {
throw BizException.saveFail();
}
return info;
}
// 查询
@GetMapping("/{id}")
public OrderInfo get(@PathVariable("id") String id) {
return orderInfoService.getById(id);
}
// 删除
@DeleteMapping("/{id}")
public boolean remove(@PathVariable("id") String id) {
if (!StringUtils.hasText(id)) throw BizException.paramError();
// 只是逻辑删除 -> 将状态更新未删除即可
return orderInfoService.updateById(
OrderInfo.builder()
.id(id)
.status(DataStatus.DELETE) // 状态设置为删除
.build()
);
}
}

View File

@ -2,6 +2,7 @@ package me.xiaoyan.point.api.pojo;
import java.util.Date; import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.extension.activerecord.Model;
@ -25,13 +26,14 @@ import java.io.Serializable;
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@Builder @Builder
@TableName(value ="order_info") @TableName(value = "order_info")
public class OrderInfo { public class OrderInfo {
@TableId @TableId
//订单编号 //订单编号
private String id; private String id;
//商品编号 //商品编号
private Long gid; private Long gid;
private String orderTitle;
//价格 //价格
private Integer price; private Integer price;
//购买数量 //购买数量
@ -48,6 +50,7 @@ public class OrderInfo {
private Date updateTime; private Date updateTime;
//订单状态(0:已删除 1:已取消 2:待确认 3:已完成) //订单状态(0:已删除 1:已取消 2:待确认 3:已完成)
private Integer status; private Integer status;
@TableField(exist = false)
private UserInfo owner;
} }

View File

@ -0,0 +1,11 @@
package me.xiaoyan.point.api.pojo.vo;
import lombok.Data;
@Data
public class OrderQueryParam extends PageParam {
private String id;
private String title;
private String createTimeStart;
private String createTimeEnd;
}

View File

@ -13,10 +13,10 @@ import lombok.experimental.Accessors;
@Accessors(chain = true) @Accessors(chain = true)
@Builder @Builder
public class PageParam { public class PageParam {
private Integer page; private Integer page = 1;
private Integer pageSize = 20; private Integer pageSize = 20;
public Page getPage(){ public Page getPage() {
return new Page().setCurrent(page).setSize(pageSize); return new Page().setCurrent(page).setSize(pageSize);
} }
} }

View File

@ -25,4 +25,5 @@ public interface GoodsService extends IService<Goods> {
boolean deductStock(int id,int count); boolean deductStock(int id,int count);
List<Goods> queryAllGoodsIdAndStock(); List<Goods> queryAllGoodsIdAndStock();
Goods queryByTitle(String title);
} }

View File

@ -1,8 +1,10 @@
package me.xiaoyan.point.api.service; package me.xiaoyan.point.api.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import me.xiaoyan.point.api.pojo.OrderInfo; import me.xiaoyan.point.api.pojo.OrderInfo;
import me.xiaoyan.point.api.pojo.vo.CreateOrderData; import me.xiaoyan.point.api.pojo.vo.CreateOrderData;
import me.xiaoyan.point.api.pojo.vo.OrderQueryParam;
/** /**
* 订单表(OrderInfo)表服务接口 * 订单表(OrderInfo)表服务接口
@ -13,5 +15,7 @@ import me.xiaoyan.point.api.pojo.vo.CreateOrderData;
public interface OrderInfoService extends IService<OrderInfo> { public interface OrderInfoService extends IService<OrderInfo> {
OrderInfo create(int uid, CreateOrderData data); OrderInfo create(int uid, CreateOrderData data);
Page queryByPage(OrderQueryParam param);
} }

View File

@ -32,7 +32,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods>
if (StringUtils.hasText(param.getTitle())) { if (StringUtils.hasText(param.getTitle())) {
q.eq("title", param.getTitle().trim()); q.eq("title", param.getTitle().trim());
} }
if(param.getCategory() != null){ if (param.getCategory() != null) {
q.eq("category", param.getCategory()); q.eq("category", param.getCategory());
} }
// 不查询删除状态数据 // 不查询删除状态数据
@ -40,6 +40,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods>
return getBaseMapper().selectPage(param.getPage(), q); return getBaseMapper().selectPage(param.getPage(), q);
} }
@Override @Override
public boolean deductStock(int id, int count) { public boolean deductStock(int id, int count) {
return getBaseMapper().deductCount(id, count) == 1; return getBaseMapper().deductCount(id, count) == 1;
@ -49,6 +50,16 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods>
public List<Goods> queryAllGoodsIdAndStock() { public List<Goods> queryAllGoodsIdAndStock() {
return getBaseMapper().queryAllGoodsIdAndStock(); return getBaseMapper().queryAllGoodsIdAndStock();
} }
@Override
public Goods queryByTitle(String title) {
if (!StringUtils.hasText(title)) {
return null;
}
QueryWrapper q = new QueryWrapper();
q.eq("title", title);
return getOne(q);
}
} }

View File

@ -1,6 +1,7 @@
package me.xiaoyan.point.api.service.impl; package me.xiaoyan.point.api.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import me.xiaoyan.point.api.error.BizException; import me.xiaoyan.point.api.error.BizException;
import me.xiaoyan.point.api.mapper.OrderInfoMapper; import me.xiaoyan.point.api.mapper.OrderInfoMapper;
@ -9,8 +10,10 @@ import me.xiaoyan.point.api.pojo.OrderInfo;
import me.xiaoyan.point.api.pojo.UserInfo; import me.xiaoyan.point.api.pojo.UserInfo;
import me.xiaoyan.point.api.pojo.dto.OrderStatus; import me.xiaoyan.point.api.pojo.dto.OrderStatus;
import me.xiaoyan.point.api.pojo.vo.CreateOrderData; import me.xiaoyan.point.api.pojo.vo.CreateOrderData;
import me.xiaoyan.point.api.pojo.vo.OrderQueryParam;
import me.xiaoyan.point.api.service.*; import me.xiaoyan.point.api.service.*;
import me.xiaoyan.point.api.util.OrderIdGenerator; import me.xiaoyan.point.api.util.OrderIdGenerator;
import me.xiaoyan.point.api.util.QueryWrapperUtil;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -78,6 +81,23 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
throw BizException.create("创建订单失败"); throw BizException.create("创建订单失败");
} }
@Override
public Page queryByPage(OrderQueryParam param) {
final QueryWrapper q = QueryWrapperUtil.builder()
.eq("id", param.getId())
.eq("order_title", param.getTitle())
.ge("create_time", param.getCreateTimeStart())
.le("create_time", param.getCreateTimeEnd())
.build();
final Page<OrderInfo> page = getBaseMapper().selectPage(param.getPage(), q);
page.getRecords().forEach(o -> {
// 查询订单的归属用户
o.setOwner(userInfoService.getById(o.getUid()));
});
return page;
}
public long buyHistoryCount(int uid, int gid) { public long buyHistoryCount(int uid, int gid) {
QueryWrapper q = new QueryWrapper(); QueryWrapper q = new QueryWrapper();
q.eq("uid", uid); q.eq("uid", uid);

View File

@ -30,6 +30,20 @@ public class QueryWrapperUtil {
return this; return this;
} }
public QueryWrapperUtil le(String column, String value) {
if (StringUtils.hasText(value)) {
q.le(column, value);
}
return this;
}
public QueryWrapperUtil ge(String column, String value) {
if (StringUtils.hasText(value)) {
q.ge(column, value);
}
return this;
}
public QueryWrapper build() { public QueryWrapper build() {
return this.q; return this.q;
} }

View File

@ -48,25 +48,25 @@ create table sign_record
create_time datetime default current_timestamp create_time datetime default current_timestamp
) engine = innodb ) engine = innodb
collate = 'utf8mb4_general_ci' comment '打卡记录表'; collate = 'utf8mb4_general_ci' comment '打卡记录表';
drop table if exists goods; drop table if exists goods;
create table goods create table goods
( (
id bigint(15) primary key auto_increment, id bigint(15) primary key auto_increment,
category tinyint(2) null default 1 comment '商品类别(1:普通 2:精选 3:秒杀 4:抽奖)', category tinyint(2) null default 1 comment '商品类别(1:普通 2:精选 3:秒杀 4:抽奖)',
type tinyint(2) null default 1 comment '商品类型(1:实物 2:虚拟)', type tinyint(2) null default 1 comment '商品类型(1:实物 2:虚拟)',
title varchar(50) not null, title varchar(50) not null,
origin_price int(10) unsigned comment '原价' default 0, origin_price int(10) unsigned comment '原价' default 0,
price int(10) unsigned not null comment '价格', price int(10) unsigned not null comment '价格',
stock int(10) unsigned not null comment '库存数量', stock int(10) unsigned not null comment '库存数量',
limit_count int(10) unsigned null default 1 comment '购买最大数量(0表示不限制)', limit_count int(10) unsigned null default 1 comment '购买最大数量(0表示不限制)',
cover varchar(200) not null comment '商品图', cover varchar(200) not null comment '商品图',
description text not null comment '描述', description text not null comment '描述',
notice varchar(500) null comment '提示', notice varchar(500) null comment '提示',
online_time datetime not null comment '上架时间', online_time datetime not null comment '上架时间',
offline_time datetime not null comment '下架时间', offline_time datetime not null comment '下架时间',
create_time datetime default current_timestamp, create_time datetime default current_timestamp,
update_time datetime null on update current_timestamp, update_time datetime null on update current_timestamp,
status tinyint(2) default 1, status tinyint(2) default 1,
index ix_title (title) index ix_title (title)
) engine = innodb ) engine = innodb
collate = 'utf8mb4_general_ci' comment '商品表'; collate = 'utf8mb4_general_ci' comment '商品表';
@ -75,6 +75,7 @@ create table order_info
( (
id varchar(50) not null comment '订单编号', id varchar(50) not null comment '订单编号',
gid bigint(15) not null comment '商品编号', gid bigint(15) not null comment '商品编号',
order_title varchar(50) null comment '订单名称',
price int(10) not null comment '价格', price int(10) not null comment '价格',
uid int(10) not null comment '用户编号', uid int(10) not null comment '用户编号',
data json null comment '订单数据', data json null comment '订单数据',

View File

@ -1,4 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="me.xiaoyan.point.api.mapper.OrderInfoMapper"> <mapper namespace="me.xiaoyan.point.api.mapper.OrderInfoMapper">
<resultMap id="orderInfoMap" type="me.xiaoyan.point.api.pojo.OrderInfo">
<association property="owner"/>
</resultMap>
<select id="selectByPage" resultMap="orderInfoMap"></select>
</mapper> </mapper>