This commit is contained in:
weipengfei 2024-04-02 18:18:48 +08:00
parent fe019ae2ea
commit b014eba006
10 changed files with 377 additions and 87 deletions

View File

@ -1,2 +1,2 @@
# VITE_BASE_URL = 'http://192.168.1.24:8324' VITE_BASE_URL = 'http://192.168.1.16:8324'
VITE_BASE_URL = 'https://crmeb-test.shop.lihaink.cn' # VITE_BASE_URL = 'https://crmeb-test.shop.lihaink.cn'

View File

@ -15,12 +15,55 @@ export function cartCreateApi(data) {
} }
/** /**
* @description 购物 * @description 购物列表
*/ */
export function cartListApi(data) { export function cartListApi(data) {
return request.get(`user/cart/lst`, { params: data }) return request.get(`user/cart/lst`, { params: data })
} }
/**
* @description 购物数量加减
*/
export function cartChangeApi(id, data) {
return request.post(`user/cart/change/${id}`, data)
}
/**
* @description 结算
*/
export function orderCheckApi(data) {
return request.post(`v2/order/check`, data)
}
/**
* @description 删除商品
*/
export function cartDeleteApi(data) {
return request.post(`user/cart/delete`, data)
}
/**
* @description 支付
*/
export function orderCreateApi(data) {
return request.post(`v2/order/create`, data)
}
/**
* @description 订单状态
*/
export function orderStatusApi(id) {
return request.get(`micropay_query`, { params: { order_id: id } })
}
/**
* @description 订单列表
*/
export function orderListApi(data) {
return request.get(`/order/list`, { params: data })
}
// /** // /**
// * @description 购物车数量 // * @description 购物车数量
// */ // */

View File

@ -1,9 +1,8 @@
<script setup> <script setup>
import myHeader from "./myHeader.vue" import myHeader from "./myHeader.vue";
import myAside from "./myAside.vue" import myAside from "./myAside.vue";
</script> </script>
<template> <template>
<div class="common-layout"> <div class="common-layout">
<el-container> <el-container>
@ -15,7 +14,9 @@ import myAside from "./myAside.vue"
<myAside></myAside> <myAside></myAside>
</el-aside> </el-aside>
<el-main> <el-main>
<transition name="el-zoom-in-top">
<router-view class="my-main"></router-view> <router-view class="my-main"></router-view>
</transition>
</el-main> </el-main>
</el-container> </el-container>
</el-container> </el-container>
@ -23,22 +24,22 @@ import myAside from "./myAside.vue"
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.common-layout{ .common-layout {
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
background-color: #001529; background-color: #001529;
.el-header{ .el-header {
color: #fff; color: #fff;
} }
.el-aside{ .el-aside {
color: #fff; color: #fff;
} }
.el-main{ .el-main {
background-color: #f5f5f5; background-color: #f5f5f5;
width: calc(100vw - 100px); width: calc(100vw - 100px);
min-height: calc(100vh - 60px); min-height: calc(100vh - 60px);
border-radius: 2rem 0 0 0; border-radius: 2rem 0 0 0;
.my-main{ .my-main {
height: 100%; height: 100%;
width: 100%; width: 100%;
} }

View File

@ -1,14 +1,26 @@
<script setup> <script setup>
import { useRoute, useRouter } from 'vue-router'
const router = useRouter()
const route = useRoute()
const navTo = (name) => {
router.push({ name })
}
</script> </script>
<template> <template>
<div class="my-card"> <div class="my-card">
<div class="list-item active"> <div class="list-item" :class="{'active': route.name=='home'}" @click="navTo('home')">
<el-icon size="30"><Sell /></el-icon> <el-icon size="30"><Sell /></el-icon>
<div>收银</div> <div>收银</div>
</div> </div>
<div class="list-item" :class="{'active': route.name=='order'}" @click="navTo('order')">
<el-icon size="30"><DataLine /></el-icon>
<div>订单</div>
</div>
</div> </div>
</template> </template>
@ -31,6 +43,7 @@
&.active { &.active {
background-color: #1890ff; background-color: #1890ff;
transition: 300ms;
} }
} }
} }

View File

@ -14,6 +14,11 @@ const routes = [
path: '/home', path: '/home',
name: 'home', name: 'home',
component: () => import('@/views/home/index.vue'), component: () => import('@/views/home/index.vue'),
},
{
path: '/order',
name: 'order',
component: () => import('@/views/order/index.vue'),
} }
] ]
}, },

View File

@ -1,4 +1,7 @@
import axios from "axios"; import axios from "axios";
import { ElMessage } from "element-plus";
import { useRouter } from "vue-router";
import { useUserStore } from "../store/user";
const request = axios.create({ const request = axios.create({
baseURL: import.meta.env.VITE_BASE_URL + '/api', baseURL: import.meta.env.VITE_BASE_URL + '/api',
@ -27,11 +30,34 @@ request.interceptors.request.use(
request.interceptors.response.use( request.interceptors.response.use(
response => { response => {
// 对响应数据做些什么,例如解析数据、统一处理错误等 // 对响应数据做些什么,例如解析数据、统一处理错误等
if (response.data.status === 401 || response.data.status === 4000) {
const router = useRouter();
ElMessage({
message: response.data.message,
type: 'error',
})
setTimeout(() => {
const userStore = useUserStore();
userStore.setUserInfo({});
userStore.setToken('');
router.push('/login');
}, 1000);
}
if (response.data.status === 400) {
ElMessage({
message: response.data.message,
type: 'error',
})
}
return response.data; return response.data;
}, },
error => { error => {
// 处理响应错误 // 处理响应错误
console.error(error); console.error(error);
ElMessage({
message: error,
type: 'error',
})
return Promise.reject(error); return Promise.reject(error);
} }
); );

View File

@ -1,24 +1,48 @@
<script setup> <script setup>
import { ref } from 'vue'; import { ref } from 'vue';
import { cartListApi } from "@/api/store.js"; import { cartListApi, cartDeleteApi, cartChangeApi } from "@/api/store.js";
const list = ref([]) const list = ref([])
const allPrice = ref(0) //
const clearAll = ()=>{ const clearAll = ()=>{
list.value = [] let cart_id = [];
list.value.map(item=>{
cart_id.push(item.cart_id);
})
if(cart_id.length==0) return;
deleteShop(cart_id);
} }
const deleteOne = (index)=>{ const deleteOne = (cart_id)=>{
list.value.splice(index,1) list.value = list.value.filter(item=>item.cart_id!=cart_id);
deleteShop([cart_id]);
} }
const getList = (item)=>{ const deleteShop = (arr)=>{
cartDeleteApi({
cart_id: arr
}).then(res=>{
console.log(res);
getList();
})
}
const getList = ()=>{
allPrice.value = 0;
cartListApi({ cartListApi({
source: 300 source: 300
}).then(res=>{ }).then(res=>{
list.value = res.data.list if(res.data?.list?.length>0) {
list.value = res.data.list[0].list;
list.value.forEach(item=>{
allPrice.value += item.productAttr.price * item.cart_num
})
}
else list.value = []
}) })
} }
getList();
const emit = defineEmits(['goPay']) const emit = defineEmits(['goPay'])
@ -26,8 +50,17 @@ const goPay = ()=>{
emit('goPay') emit('goPay')
} }
const changeCartNum = (val)=>{
cartChangeApi(val.cart_id, {
cart_num: val.cart_num
}).then(res=>{
})
}
defineExpose({ defineExpose({
getList getList,
list
}) })
</script> </script>
@ -36,22 +69,22 @@ defineExpose({
<template> <template>
<div class="my-order"> <div class="my-order">
<div class="header-nav"> <div class="header-nav">
<div class="nav-item">已选购 <span>{{ 0 }}</span> </div> <div class="nav-item">已选购 <span>{{ list.length }}</span> </div>
<div class="nav-item-clear" @click="clearAll"><el-icon><Delete /></el-icon></div> <div class="nav-item-clear" @click="clearAll"><el-icon><Delete /></el-icon></div>
</div> </div>
<div class="order-list"> <div class="order-list">
<el-empty v-if="list.length==0" description="请点击右侧添加商品" /> <el-empty v-if="list.length==0" description="请点击右侧添加商品" />
<div v-else class="order-item" v-for="(item, index) in list" :key="index"> <div v-else class="order-item" v-for="(item, index) in list" :key="index">
<el-image class="order-item-img" src="https://multi-store.crmeb.net/uploads/attach/2024/03/01/8149b6d6bfc22ad622ec478528310c43.jpg"></el-image> <el-image class="order-item-img" :src="(item.productAttr && item.productAttr.image) || item.product.image"></el-image>
<div class="order-item-info"> <div class="order-item-info">
<div class="order-item-title"> <div class="order-item-title">
<div class="title">很不错的商品名称很不错的商品名称很不错的商品名称很不错的商品名称</div> <div class="title">{{ item.spu.store_name }}</div>
<div class="delete" @click="deleteOne">删除</div> <div class="delete" @click="deleteOne(item.cart_id)">删除</div>
</div> </div>
<div class="order-item-sku">设备规格</div> <div class="order-item-sku">设备规格</div>
<div class="order-item-price"> <div class="order-item-price">
<div>¥<span>100</span></div> <div>¥<span>{{ item.productAttr.price }}</span></div>
<div><el-input-number v-model="item.num" :min="1" :step="1" /></div> <div><el-input-number v-model="item.cart_num" step-strictly :min="1" :step="1" @change="changeCartNum(item)"/></div>
</div> </div>
</div> </div>
</div> </div>
@ -59,7 +92,7 @@ defineExpose({
<div class="order-footer"> <div class="order-footer">
<div class="order-total"> <div class="order-total">
<div class="price"> <div class="price">
<div class="total-item">实付: <span>¥<span style="font-size: 1.4rem;">{{ 10000.65 }}</span></span></div> <div class="total-item">实付: <span>¥<span style="font-size: 1.4rem;">{{ allPrice.toFixed(2) }}</span></span></div>
<div class="total-item">优惠: <span>¥<span>{{ 0 }}</span></span></div> <div class="total-item">优惠: <span>¥<span>{{ 0 }}</span></span></div>
</div> </div>
<div class="update-price"><el-button class="btn" type="primary">改价</el-button></div> <div class="update-price"><el-button class="btn" type="primary">改价</el-button></div>

View File

@ -1,3 +1,96 @@
<script setup>
import { ref, watch, nextTick } from "vue";
import { orderCreateApi, orderStatusApi } from "@/api/store.js";
import { ElMessage} from 'element-plus';
const drawer = ref(false);
const active = ref(1);
const input = ref("");
const codeRef = ref("");
const cancelClick = () => {
codeRef.value.blur();
drawer.value = false;
};
const open = ()=>{
nextTick(()=>{
setTimeout(()=>{
loading.value = false;
input.value = "";
codeRef.value.focus();
},300)
})
}
const form = ref({});
const cart_id = ref([]);
const setForm = (e) => {
form.value = e.data;
cart_id.value = e.cart_id;
console.log(e, cart_id.value);
}
const emit = defineEmits(['paySuccess']);
//
const handleEnter = ()=>{
loading.value = true;
codeRef.value.blur();
orderCreateApi({
address_id: "",
key: form.value.key,
cart_id: cart_id.value,
pay_type: 'micropay',
auth_code: input.value,
source: 300
}).then(res=>{
if(res.data.status=='success'){
drawer.value = false;
ElMessage({
message: '支付成功',
type: 'success',
})
loading.value = false;
input.value = "";
emit('paySuccess');
}else {
getOrderStatus(res.data.result.order_id)
}
})
}
const getOrderStatus = (id)=>{
orderStatusApi(id).then(res=>{
if(res.data.paid==1){
ElMessage({
message: '支付成功',
type: 'success',
})
loading.value = false;
}else {
ElMessage({
message: '支付失败',
type: 'error',
})
loading.value = false;
}
}).catch(err=>{
setTimeout(()=>{
getOrderStatus(id);
}, 5000)
})
}
const loading = ref(false);
defineExpose({
drawer,
setForm
});
</script>
<template> <template>
<el-drawer :size="800" v-model="drawer" direction="rtl" @open="open"> <el-drawer :size="800" v-model="drawer" direction="rtl" @open="open">
<template #header> <template #header>
@ -10,13 +103,14 @@
<div class="right" :class="{'active': active==2}" @click="active=2">现金收款</div> <div class="right" :class="{'active': active==2}" @click="active=2">现金收款</div>
</div> </div>
<div style="color: #999;padding: 2rem 0 0.3rem 0;">应收金额(): </div> <div style="color: #999;padding: 2rem 0 0.3rem 0;">应收金额(): </div>
<div style="color: #f5222d;padding-bottom: 2rem;">¥<span style="font-size: 1.6rem;">{{ '0.00' }}</span></div> <div style="color: #f5222d;padding-bottom: 2rem;">¥<span style="font-size: 1.6rem;">{{ form.total_price }}</span></div>
<div class="card1" v-if="active==1"> <div v-loading="loading" element-loading-text="支付中" class="card1" v-if="active==1">
<el-input ref="codeRef" v-model="input" autofocus class="code-input" placeholder="请点击输入框聚焦扫码或输入编码号" /> <el-input ref="codeRef" v-model="input" autofocus class="code-input" placeholder="请点击输入框聚焦扫码或输入编码号" @keyup.enter="handleEnter"/>
<div class="tips"></div> <div class="tips"></div>
</div> </div>
<div class="card2" v-else> <div class="card2" v-else>
<el-input ref="codeRef" v-model="input" autofocus class="code-input" placeholder="请点击输入框输入金额" /> <div>现金收款正在开发中</div>
<!-- <el-input ref="codeRef" v-model="input" autofocus class="code-input" placeholder="请点击输入框输入金额" /> -->
</div> </div>
</div> </div>
</template> </template>
@ -26,32 +120,8 @@
</div> </div>
</template> </template>
</el-drawer> </el-drawer>
</template> </template>
<script setup>
import { ref, watch, nextTick } from "vue";
const drawer = ref(false);
const active = ref(1);
const input = ref("");
const codeRef = ref("");
const cancelClick = () => {
drawer.value = false;
};
const open = ()=>{
nextTick(()=>{
setTimeout(()=>{
codeRef.value.focus();
},300)
})
}
defineExpose({
drawer,
});
</script>
<style lang="scss" scoped> <style lang="scss" scoped>
.dra-body { .dra-body {

View File

@ -5,7 +5,7 @@ import padding from "./component/padding.vue";
import pupop from "./component/pupop.vue"; import pupop from "./component/pupop.vue";
import pay from "./component/pay.vue"; import pay from "./component/pay.vue";
import { ref, nextTick } from "vue"; import { ref, nextTick } from "vue";
import { storeListApi, cartCreateApi } from "@/api/store.js"; import { storeListApi, cartCreateApi, orderCheckApi } from "@/api/store.js";
import { useUserStore } from "@/store/user.js"; import { useUserStore } from "@/store/user.js";
const pupopRef = ref(null); const pupopRef = ref(null);
@ -56,17 +56,37 @@ const changeItem = (item, change = "") => {
// sale_type: 1 // sale_type: 1
}; };
cartCreateApi(q).then((res) => { cartCreateApi(q).then((res) => {
console.log(res); orderRef.value.getList();
orderRef.value.getList(item); });
};
//
const checkOut = () => {
let cart_id = orderRef.value.list.map((item) => item.cart_id);
orderCheckApi({
takes: [],
use_coupon: {},
use_integral: false,
cart_id: cart_id,
}).then((res) => {
payRef.value.setForm({
data: res.data,
cart_id: cart_id,
});
}); });
}; };
getStoreList(); getStoreList();
const goPay = () => { const goPay = () => {
checkOut();
payRef.value.drawer = true; payRef.value.drawer = true;
}; };
const paySuccess = ()=>{
orderRef.value.getList();
}
nextTick(() => { nextTick(() => {
// pupopRef.value.show(true); // pupopRef.value.show(true);
}); });
@ -84,7 +104,7 @@ nextTick(() => {
@changeItem="changeItem" @changeItem="changeItem"
/> />
<pupop ref="pupopRef" /> <pupop ref="pupopRef" />
<pay ref="payRef" /> <pay ref="payRef" @paySuccess="paySuccess"/>
</div> </div>
</template> </template>

79
src/views/order/index.vue Normal file
View File

@ -0,0 +1,79 @@
<script setup>
import { ref } from 'vue'
import { orderListApi } from "@/api/store.js"
const orderList = ref([])
const where = ref({
page: 1,
limit: 20,
status: -2
})
const loading = ref(false)
const total = ref(0)
const getOrderList = () => {
loading.value = true;
orderListApi(where.value).then((res) => {
orderList.value = res.data.list;
total.value = res.data.count;
loading.value = false;
})
}
getOrderList()
</script>
<template>
<div v-loading="loading" element-loading-text="加载中" class="my-order">
<el-table :data="orderList" stripe style="width: 100%">
<el-table-column prop="group_order_id" label="ID" width="100" />
<el-table-column prop="order_sn" label="订单号" min-width="250" />
<el-table-column prop="total_price" label="订单金额" />
<el-table-column prop="paid" label="支付状态">
<template #default="scope">
<span v-if="scope.row.paid==1">已支付</span>
<span v-else>未支付</span>
</template>
</el-table-column>
<el-table-column prop="pay_time" label="支付时间" />
</el-table>
<el-pagination
:page-size="where.limit"
layout="prev, pager, next"
:total="total"
/>
</div>
</template>
<style lang="scss" scoped>
.my-order {
background-color: #fff;
border-radius: 1.2rem;
box-sizing: border-box;
padding: 1rem;
}
/* 修改滚动条的样式 */
::-webkit-scrollbar {
width: 5px; /* 设置滚动条的宽度 */
}
/* 设置滚动条的轨道样式 */
::-webkit-scrollbar-track {
background-color: #f1f1f1; /* 设置轨道的背景色 */
margin: 20px 0;
}
/* 设置滚动条的滑块样式 */
::-webkit-scrollbar-thumb {
background-color: #ccc; /* 设置滑块的背景色 */
border-radius: 5px; /* 设置滑块的圆角 */
}
/* 设置滚动条鼠标悬停时的滑块样式 */
::-webkit-scrollbar-thumb:hover {
background-color: #999; /* 设置鼠标悬停时滑块的背景色 */
}
</style>