This commit is contained in:
parent
25be510191
commit
0613c96862
|
@ -1,10 +1,10 @@
|
||||||
VITE_NOW_TYPE = 'dist'
|
VITE_NOW_TYPE = 'dist'
|
||||||
|
|
||||||
# VITE_PUSH_URL = 'ws://192.168.1.22:8787'
|
VITE_PUSH_URL = 'ws://192.168.1.22:8787'
|
||||||
# VITE_BASE_URL = 'http://192.168.1.22:8545'
|
VITE_BASE_URL = 'http://192.168.1.22:8545'
|
||||||
|
|
||||||
VITE_PUSH_URL ='wss://test-multi-store.lihaink.cn/pull'
|
# VITE_PUSH_URL ='wss://test-multi-store.lihaink.cn/pull'
|
||||||
VITE_BASE_URL = 'https://test-multi-store.lihaink.cn'
|
# VITE_BASE_URL = 'https://test-multi-store.lihaink.cn'
|
||||||
|
|
||||||
# VITE_PUSH_URL ='wss://multi-store.lihaink.cn/pull'
|
# VITE_PUSH_URL ='wss://multi-store.lihaink.cn/pull'
|
||||||
# VITE_BASE_URL = 'https://multi-store.lihaink.cn'
|
# VITE_BASE_URL = 'https://multi-store.lihaink.cn'
|
|
@ -0,0 +1,31 @@
|
||||||
|
import request from '@/utils/axiosAPI.js'
|
||||||
|
|
||||||
|
// 省
|
||||||
|
export function apiProvince() {
|
||||||
|
return request.get('/province')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 市
|
||||||
|
export function apiCity(data) {
|
||||||
|
return request.get('/city', { params: data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 区
|
||||||
|
export function apiArea(data) {
|
||||||
|
return request.get('/area', { params: data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 街道
|
||||||
|
export function apiStreet(data) {
|
||||||
|
return request.get('/street', { params: data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 村
|
||||||
|
export function apiVillage(data) {
|
||||||
|
return request.get('/village', { params: data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 队
|
||||||
|
export function apiBrigade(data) {
|
||||||
|
return request.get('/brigade', { params: data })
|
||||||
|
}
|
|
@ -74,7 +74,7 @@ export function saleStoreListApi(data) {
|
||||||
* @description 店铺商品分类
|
* @description 店铺商品分类
|
||||||
*/
|
*/
|
||||||
export function merchantCategoryListApi(data) {
|
export function merchantCategoryListApi(data) {
|
||||||
return request.get(`goods/goodsclass/lists`, { params: data })
|
return request.get(`/cate/cate/lists`, { params: data })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,3 +26,24 @@ export function info(data) {
|
||||||
export function logout() {
|
export function logout() {
|
||||||
return request.post(`logout`)
|
return request.post(`logout`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 会员类型
|
||||||
|
*/
|
||||||
|
export function userShipApi() {
|
||||||
|
return request.get(`/user/UserShip/lists`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 添加会员
|
||||||
|
*/
|
||||||
|
export function userAddApi(data) {
|
||||||
|
return request.post(`/user/user/add`, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 会员列表
|
||||||
|
*/
|
||||||
|
export function userListsApi() {
|
||||||
|
return request.get(`/user/user/lists`)
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
const config = {
|
const config = {
|
||||||
url: import.meta.env.VITE_BASE_URL + '/store',
|
url: import.meta.env.VITE_BASE_URL + '/store',
|
||||||
upload: import.meta.env.VITE_BASE_URL + '/store/upload/image/field',
|
upload: import.meta.env.VITE_BASE_URL + '/store/upload/image/field',
|
||||||
|
api: import.meta.env.VITE_BASE_URL + '/api',
|
||||||
}
|
}
|
||||||
|
|
||||||
export default config;
|
export default config;
|
|
@ -43,6 +43,7 @@ const newOrder = (e) => {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
isPlaying = false;
|
isPlaying = false;
|
||||||
|
ElMessage.error('播放失败');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -82,6 +83,12 @@ const list = ref([
|
||||||
ico: "Van",
|
ico: "Van",
|
||||||
count: 0,
|
count: 0,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "user",
|
||||||
|
title: "用户",
|
||||||
|
ico: "User",
|
||||||
|
count: 0,
|
||||||
|
},
|
||||||
// { name: "purchaseOrder", title: "采购订单", ico: "Van", count: 0 },
|
// { name: "purchaseOrder", title: "采购订单", ico: "Van", count: 0 },
|
||||||
// { name: "orderCount", title: "订单统计", ico: "DocumentRemove", count: 0 },
|
// { name: "orderCount", title: "订单统计", ico: "DocumentRemove", count: 0 },
|
||||||
// { name: "wallet", title: "余额提现", ico: "Wallet", count: 0 },
|
// { name: "wallet", title: "余额提现", ico: "Wallet", count: 0 },
|
||||||
|
|
|
@ -59,6 +59,12 @@ const routes = [
|
||||||
meta: { title: '入库登记' },
|
meta: { title: '入库登记' },
|
||||||
component: () => import('@/views/putStorage/index.vue'),
|
component: () => import('@/views/putStorage/index.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/user',
|
||||||
|
name: 'user',
|
||||||
|
meta: { title: '用户' },
|
||||||
|
component: () => import('@/views/user/index.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/test',
|
path: '/test',
|
||||||
name: 'test',
|
name: 'test',
|
||||||
|
|
|
@ -116,7 +116,7 @@ export const printTicket = (obj = {}, test = false) => {
|
||||||
if(!obj || !obj.order_id) obj = testObj;
|
if(!obj || !obj.order_id) obj = testObj;
|
||||||
str += Esc.Size2(2) + Esc.Center() + Esc.boldFontOn() + obj.system_store_name + Esc.Size1() + "\n";
|
str += Esc.Size2(2) + Esc.Center() + Esc.boldFontOn() + obj.system_store_name + Esc.Size1() + "\n";
|
||||||
str += Esc.fillLine(" ") + Esc.boldFontOff() + "\n";
|
str += Esc.fillLine(" ") + Esc.boldFontOff() + "\n";
|
||||||
if(obj.shipping_type == 2) str += Esc.Left() + "核销码: " + Esc.boldFontOn() + obj.verify_code + Esc.boldFontOff() + "\n";
|
if(obj.shipping_type) str += Esc.Left() + "核销码: " + Esc.boldFontOn() + obj.verify_code + Esc.boldFontOff() + "\n";
|
||||||
str += Esc.Left() + "单号: " + obj.order_id + "\n";
|
str += Esc.Left() + "单号: " + obj.order_id + "\n";
|
||||||
str += Esc.Left() + "下单时间: " + obj.create_time + "\n";
|
str += Esc.Left() + "下单时间: " + obj.create_time + "\n";
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
import axios from "axios";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
import router from "@/router/index.js";
|
||||||
|
import { useUserStore } from "../store/user";
|
||||||
|
import config from "@/config";
|
||||||
|
|
||||||
|
const request = axios.create({
|
||||||
|
baseURL: config.api,
|
||||||
|
timeout: 60000
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 请求拦截器
|
||||||
|
request.interceptors.request.use(
|
||||||
|
config => {
|
||||||
|
// 在发送请求之前做些什么,例如添加token、修改请求头等
|
||||||
|
const token = localStorage.getItem('Token');
|
||||||
|
if (token) {
|
||||||
|
config.headers['token'] = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
// 处理请求错误
|
||||||
|
console.error(error);
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 响应拦截器
|
||||||
|
request.interceptors.response.use(
|
||||||
|
response => {
|
||||||
|
// 对响应数据做些什么,例如解析数据、统一处理错误等
|
||||||
|
if (response.data.code === -1 && (response.data.msg == '登录过期' || response.data.msg == '登录超时,请重新登录')) {
|
||||||
|
ElMessage({
|
||||||
|
message: response.data.msg,
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
const userStore = useUserStore();
|
||||||
|
userStore.setUserInfo({});
|
||||||
|
userStore.setToken('');
|
||||||
|
router.push('/login');
|
||||||
|
}, 500)
|
||||||
|
throw new Error(response.data.msg);
|
||||||
|
}
|
||||||
|
if (response.data.code === 400) {
|
||||||
|
ElMessage({
|
||||||
|
message: response.data.msg,
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
|
throw new Error(response.data.msg);
|
||||||
|
}
|
||||||
|
if (response.data.show) {
|
||||||
|
ElMessage({
|
||||||
|
message: response.data.msg,
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (response.data.code === 500) {
|
||||||
|
response.data.msg = JSON.parse(response.data.msg);
|
||||||
|
ElMessage({
|
||||||
|
message: response.data.msg?.msg || response.data.msg,
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
|
throw new Error(response.data.msg);
|
||||||
|
}
|
||||||
|
// console.log(response.data);
|
||||||
|
if (response.data.code === 0) {
|
||||||
|
return Promise.reject(response.data)
|
||||||
|
}
|
||||||
|
return response.data;
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
// 处理响应错误
|
||||||
|
console.error(error);
|
||||||
|
ElMessage({
|
||||||
|
message: error.response?.data?.msg || error,
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export default request;
|
|
@ -120,6 +120,11 @@ const getDetail = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 备货
|
||||||
|
const stockUp = () => {
|
||||||
|
console.log('备货');
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
mitt.on("set-sale-order-detail", (res) => {
|
mitt.on("set-sale-order-detail", (res) => {
|
||||||
console.log("===", res);
|
console.log("===", res);
|
||||||
|
@ -204,6 +209,11 @@ onUnmounted(() => {
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<el-button v-if="formData.is_writeoff === 0" type="primary" size="large" :disabled="formData.is_writeoff"
|
||||||
|
@click="stockUp">备货</el-button>
|
||||||
|
<div v-else-if="formData.is_writeoff === 1">等待用户自提</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<el-empty></el-empty>
|
<el-empty></el-empty>
|
||||||
|
@ -221,13 +231,14 @@ onUnmounted(() => {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.detail {
|
.detail {
|
||||||
height: calc(100vh - 100px - 4rem);
|
height: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.table {
|
.table {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
padding-bottom: 6rem;
|
padding-bottom: 6rem;
|
||||||
|
box-sizing: border-box;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
|
@ -260,6 +271,21 @@ onUnmounted(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 6rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 2rem;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,77 +1,103 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, onMounted, onUnmounted, nextTick } from "vue";
|
import { ref, watch, onMounted, onUnmounted, nextTick } from "vue";
|
||||||
import { merchantCategoryListApi } from "@/api/shop.js";
|
import { merchantCategoryListApi } from "@/api/shop.js";
|
||||||
|
import { useUserStore } from '@/store/user.js'
|
||||||
|
|
||||||
const emit = defineEmits(["getStoreList"]);
|
const emit = defineEmits(["getStoreList"]);
|
||||||
|
|
||||||
const categoryList = ref([]);
|
const categoryList = ref([]);
|
||||||
|
const categoryList2 = ref([]);
|
||||||
|
const categoryList3 = ref([]);
|
||||||
const active = ref(-1);
|
const active = ref(-1);
|
||||||
const cactive = ref(-1);
|
const cactive = ref(-1);
|
||||||
|
const dactive = ref(-1);
|
||||||
const sactive = ref(-1);
|
const sactive = ref(-1);
|
||||||
const show = ref(false);
|
const show = ref(false);
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
const getCategoryList = () => {
|
const getCategoryList = () => {
|
||||||
merchantCategoryListApi().then((res) => {
|
merchantCategoryListApi({
|
||||||
|
pid: 0,
|
||||||
|
page_no: 1,
|
||||||
|
page_size: 30,
|
||||||
|
level: 1,
|
||||||
|
store_id: userStore.userInfo.store_id
|
||||||
|
}).then((res) => {
|
||||||
categoryList.value = res.data.lists;
|
categoryList.value = res.data.lists;
|
||||||
active.value = -1;
|
active.value = -1;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// getCategoryList();
|
getCategoryList();
|
||||||
|
|
||||||
const changeActive = (index=-1, idnexc=-1) => {
|
const getCategoryList2 = (pid) => {
|
||||||
|
merchantCategoryListApi({
|
||||||
|
pid: pid,
|
||||||
|
page_no: 1,
|
||||||
|
page_size: 30,
|
||||||
|
level: 2,
|
||||||
|
store_id: userStore.userInfo.store_id
|
||||||
|
}).then((res) => {
|
||||||
|
categoryList2.value = res.data.lists;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCategoryList3 = (pid) => {
|
||||||
|
merchantCategoryListApi({
|
||||||
|
pid: pid,
|
||||||
|
page_no: 1,
|
||||||
|
page_size: 30,
|
||||||
|
level: 3,
|
||||||
|
store_id: userStore.userInfo.store_id
|
||||||
|
}).then((res) => {
|
||||||
|
categoryList3.value = res.data.lists;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const changeActive = (index = -1, type = 1) => {
|
||||||
sactive.value = index;
|
sactive.value = index;
|
||||||
active.value = index;
|
|
||||||
cactive.value = idnexc;
|
|
||||||
console.log(index, idnexc);
|
|
||||||
show.value = true;
|
show.value = true;
|
||||||
let mer_cate_id = '';
|
let cate_id = '';
|
||||||
if(index>=0 &&idnexc>=0) mer_cate_id = categoryList.value[index].children[idnexc].store_category_id;
|
let class_all = '';
|
||||||
else if(index>=0) mer_cate_id = categoryList.value[index].store_category_id;
|
if (type == 1) {
|
||||||
|
active.value = index;
|
||||||
|
cactive.value = -1;
|
||||||
|
dactive.value = -1;
|
||||||
|
if (index!=-1) class_all = categoryList.value[index].id;
|
||||||
|
getCategoryList2(class_all);
|
||||||
|
}
|
||||||
|
else if (type == 2) {
|
||||||
|
cactive.value = index;
|
||||||
|
dactive.value = -1;
|
||||||
|
if (index!=-1) class_all = categoryList2.value[index].id;
|
||||||
|
getCategoryList3(class_all);
|
||||||
|
}
|
||||||
emit("getStoreList", {
|
emit("getStoreList", {
|
||||||
mer_cate_id: mer_cate_id,
|
cate_id: cate_id,
|
||||||
|
class_all: class_all
|
||||||
}, true);
|
}, true);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="classify" @mouseout="show?show=false:show=true">
|
<div class="classify" @mouseout="show ? show = false : show = true">
|
||||||
<div
|
<div class="itemP" :class="{ 'itemP-active': -1 == active }" @click="changeActive(-1)">
|
||||||
class="itemP"
|
|
||||||
:class="{ 'itemP-active': -1 == active }"
|
|
||||||
@click="changeActive(-1)"
|
|
||||||
>
|
|
||||||
{{ '全部' }}
|
{{ '全部' }}
|
||||||
</div>
|
</div>
|
||||||
<el-popover
|
<el-popover placement="left" width="20rem" trigger="click" v-for="(item, index) in categoryList" :key="index"
|
||||||
placement="left"
|
:visible="index == active && sactive == index">
|
||||||
width="20rem"
|
|
||||||
trigger="click"
|
|
||||||
v-for="(item, index) in categoryList"
|
|
||||||
:key="index"
|
|
||||||
:visible="index==active && sactive==index"
|
|
||||||
>
|
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<div
|
<div class="itemP" :class="{ 'itemP-active': index == active }" @click="changeActive(index)"
|
||||||
class="itemP"
|
@mousemove="sactive = index">
|
||||||
:class="{ 'itemP-active': index == active }"
|
|
||||||
@click="changeActive(index)"
|
|
||||||
@mousemove="sactive=index"
|
|
||||||
>
|
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="active-card"
|
<div class="active-card" @mouseout="sactive = -1" @mousemove="sactive = index">
|
||||||
@mouseout="sactive=-1" @mousemove="sactive=index">
|
|
||||||
<div class="title">{{ item.name }}</div>
|
<div class="title">{{ item.name }}</div>
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<div
|
<div :class="{ 'list-active': indexc == cactive }" link type="primary"
|
||||||
:class="{ 'list-active': indexc == cactive }"
|
v-for="(chil, indexc) in categoryList2" :key="chil.id" @click="changeActive(indexc, 2)">
|
||||||
link
|
|
||||||
type="primary"
|
|
||||||
v-for="(chil, indexc) in item.children"
|
|
||||||
:key="indexc"
|
|
||||||
@click="changeActive(index, indexc)"
|
|
||||||
>
|
|
||||||
{{ chil.name }}
|
{{ chil.name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -97,10 +123,13 @@ const changeActive = (index=-1, idnexc=-1) => {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-radius: 3rem;
|
border-radius: 3rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
white-space: nowrap; /* 防止文本换行 */
|
white-space: nowrap;
|
||||||
|
/* 防止文本换行 */
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis; /* 多余文本使用省略号显示 */
|
text-overflow: ellipsis;
|
||||||
|
/* 多余文本使用省略号显示 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.itemP-active {
|
.itemP-active {
|
||||||
background-color: #1890ff;
|
background-color: #1890ff;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
@ -113,19 +142,23 @@ const changeActive = (index=-1, idnexc=-1) => {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
div {
|
div {
|
||||||
margin-right: 1rem;
|
margin-right: 1rem;
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-active {
|
.list-active {
|
||||||
color: #1890ff;
|
color: #1890ff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 修改滚动条的样式 */
|
/* 修改滚动条的样式 */
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -202,8 +202,8 @@ onUnmounted(() => {
|
||||||
@loadMore="loadMore"
|
@loadMore="loadMore"
|
||||||
/>
|
/>
|
||||||
<pupop ref="pupopRef" @changeItem="cartAddInfo" />
|
<pupop ref="pupopRef" @changeItem="cartAddInfo" />
|
||||||
<!-- <padding />
|
<padding />
|
||||||
<classify ref="classifyRef" @getStoreList="getStoreList"/> -->
|
<classify ref="classifyRef" @getStoreList="getStoreList"/>
|
||||||
<pay ref="payRef" @paySuccess="paySuccess" />
|
<pay ref="payRef" @paySuccess="paySuccess" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, onUnmounted, reactive } from "vue";
|
||||||
|
import { apiProvince, apiCity, apiArea, apiStreet, apiVillage, apiBrigade } from '@/api/public'
|
||||||
|
import { userShipApi, userAddApi } from "@/api/user"
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
|
const options = ref([]);
|
||||||
|
|
||||||
|
const formDataRef = ref(null);
|
||||||
|
const formDataInfo = reactive({
|
||||||
|
mobile: '',
|
||||||
|
user_ship: '',
|
||||||
|
selectedValues: [],
|
||||||
|
})
|
||||||
|
|
||||||
|
const formDataRules = reactive({
|
||||||
|
mobile: [
|
||||||
|
{ required: true, message: '请输入手机号', trigger: 'blur' },
|
||||||
|
{ pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
user_ship: [
|
||||||
|
{ required: true, message: '请选择会员类型', trigger: 'change' }
|
||||||
|
],
|
||||||
|
selectedValues: [
|
||||||
|
{ required: true, message: '请选择用户地址', trigger: 'change' }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// 异步加载数据的方法
|
||||||
|
const loadOptions = async (node, resolve) => {
|
||||||
|
const level = node.level;
|
||||||
|
let response;
|
||||||
|
if (level !== 0 && !node.data.code) return resolve([]);
|
||||||
|
// if (level === 0) {
|
||||||
|
// response = await apiProvince();
|
||||||
|
// response = response.data.map((item) => {
|
||||||
|
// return {
|
||||||
|
// code: item.province_code,
|
||||||
|
// name: item.province_name
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// } else
|
||||||
|
if (level === 0) {
|
||||||
|
response = await apiCity({
|
||||||
|
province_code: 510000 // 四川省
|
||||||
|
});
|
||||||
|
response = response.data.map((item) => {
|
||||||
|
return {
|
||||||
|
code: item.city_code,
|
||||||
|
name: item.city_name
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (level === 1) {
|
||||||
|
response = await apiArea({
|
||||||
|
city_code: node.data.code
|
||||||
|
});
|
||||||
|
response = response.data.map((item) => {
|
||||||
|
return {
|
||||||
|
code: item.area_code,
|
||||||
|
name: item.area_name
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if (level === 2) {
|
||||||
|
response = await apiStreet({
|
||||||
|
area_code: node.data.code
|
||||||
|
});
|
||||||
|
response = response.data.map((item) => {
|
||||||
|
return {
|
||||||
|
code: item.street_code,
|
||||||
|
name: item.street_name,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if (level === 3) {
|
||||||
|
response = await apiVillage({
|
||||||
|
street_code: node.data.code
|
||||||
|
});
|
||||||
|
response = response.data.map((item) => {
|
||||||
|
return {
|
||||||
|
code: item.village_code,
|
||||||
|
name: item.village_name,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if (level === 4) {
|
||||||
|
response = await apiBrigade({
|
||||||
|
village_code: node.data.code
|
||||||
|
});
|
||||||
|
response = response.data.map((item) => {
|
||||||
|
return {
|
||||||
|
code: item.id,
|
||||||
|
name: item.brigade_name,
|
||||||
|
leaf: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(response);
|
||||||
|
};
|
||||||
|
const props = {
|
||||||
|
value: 'code',
|
||||||
|
label: 'name',
|
||||||
|
children: 'children',
|
||||||
|
multiple: false,
|
||||||
|
lazy: true,
|
||||||
|
lazyLoad: loadOptions
|
||||||
|
};
|
||||||
|
|
||||||
|
const userShip = ref([])
|
||||||
|
const getUserShip = () => {
|
||||||
|
userShipApi().then(res => {
|
||||||
|
userShip.value = res.data.lists
|
||||||
|
})
|
||||||
|
}
|
||||||
|
getUserShip()
|
||||||
|
|
||||||
|
const emit = defineEmits(['close'])
|
||||||
|
const addUser = () => {
|
||||||
|
formDataRef.value.validate(async (valid) => {
|
||||||
|
if (valid) {
|
||||||
|
let forms = {};
|
||||||
|
forms.mobile = formDataInfo.mobile;
|
||||||
|
forms.user_ship = formDataInfo.user_ship;
|
||||||
|
forms.province = "510000";
|
||||||
|
forms.city = formDataInfo.selectedValues[0]
|
||||||
|
forms.area = formDataInfo.selectedValues[1]
|
||||||
|
forms.street = formDataInfo.selectedValues[2]
|
||||||
|
forms.village = formDataInfo.selectedValues[3]
|
||||||
|
forms.brigade = formDataInfo.selectedValues[4]
|
||||||
|
userAddApi(forms).then(res=>{
|
||||||
|
emit('close')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
addUser
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="add-user">
|
||||||
|
<el-form :model="formDataInfo" :rules="formDataRules" ref="formDataRef" label-width="80px">
|
||||||
|
<el-form-item label="会员电话" prop="mobile">
|
||||||
|
<el-input v-model="formDataInfo.mobile" placeholder="请输入会员电话" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="会员类型" prop="user_ship">
|
||||||
|
<el-select v-model="formDataInfo.user_ship" placeholder="请选择会员类型" style="width: 100%;">
|
||||||
|
<el-option v-for="item in userShip" :key="item.id" :label="item.title" :value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="用户地址" prop="selectedValues">
|
||||||
|
<el-cascader style="width: 100%;" v-model="formDataInfo.selectedValues" :options="options"
|
||||||
|
:props="props" :load="loadOptions" class="w-full" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,151 @@
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, onUnmounted, ref } from "vue";
|
||||||
|
import { useUserStore } from "@/store/user.js";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
import mitt from "@/utils/mitt.js";
|
||||||
|
import pay from "@/components/pay.vue";
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const formData = ref({
|
||||||
|
id: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
mitt.on("set-user-detail", (res) => {
|
||||||
|
console.log("===", res);
|
||||||
|
formData.value = res;
|
||||||
|
where.value.page_no = 1;
|
||||||
|
where.value.loadend = false;
|
||||||
|
where.value.loading = false;
|
||||||
|
goods_list.value = [];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
mitt.off("set-user-detail");
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="my-order">
|
||||||
|
<div class="detail" v-if="formData.id">
|
||||||
|
<div class="table" >
|
||||||
|
<div class="table-title">用户信息</div>
|
||||||
|
<div class="table-info">
|
||||||
|
<div class="info-item">
|
||||||
|
<div class="info-item-title">头像:</div>
|
||||||
|
<div class="info-item-info">
|
||||||
|
<el-avatar style="width: 4rem;height: 4rem;" :src="formData.avatar" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<div class="info-item-title">用户昵称:</div>
|
||||||
|
<div class="info-item-info">{{ formData.nickname }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<div class="info-item-title">ID:</div>
|
||||||
|
<div class="info-item-info">{{ formData.id }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<div class="info-item-title">用户电话:</div>
|
||||||
|
<div class="info-item-info">{{ formData.mobile }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<div class="info-item-title">用户账号:</div>
|
||||||
|
<div class="info-item-info">{{ formData.account }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<div class="info-item-title">创建时间:</div>
|
||||||
|
<div class="info-item-info">{{ formData.create_time }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<div class="info-item-title">用户类型:</div>
|
||||||
|
<div class="info-item-info">
|
||||||
|
<el-tag type="primary" v-if="formData.user_ship==0">{{ formData.user_ship_name }}</el-tag>
|
||||||
|
<el-tag type="success" v-else>{{ formData.user_ship_name }}</el-tag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<div class="info-item-title">用户余额:</div>
|
||||||
|
<div class="info-item-info">¥{{ formData.user_money }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<el-empty></el-empty>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.my-order {
|
||||||
|
border-radius: 1.2rem;
|
||||||
|
height: 100%;
|
||||||
|
flex: 1;
|
||||||
|
background-color: #fff;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.detail {
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.table {
|
||||||
|
padding: 1rem;
|
||||||
|
padding-bottom: 6rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow-y: auto;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.table-title {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-info {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
color: #777;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
width: 33%;
|
||||||
|
display: flex;
|
||||||
|
padding-top: 1rem;
|
||||||
|
|
||||||
|
.info-item-title {
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding-right: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 6rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 2rem;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,219 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, onUnmounted } from "vue";
|
||||||
|
import {
|
||||||
|
userListsApi
|
||||||
|
} from "@/api/user.js";
|
||||||
|
import { useUserStore } from "@/store/user.js";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
import mitt from "@/utils/mitt.js";
|
||||||
|
import moment from "moment";
|
||||||
|
import add from './add.vue';
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const props = defineProps({
|
||||||
|
isSystem: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
source: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const lists = ref([]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const where = ref({
|
||||||
|
page_no: 1,
|
||||||
|
page_size: 20,
|
||||||
|
order_id: "",
|
||||||
|
start_time: "",
|
||||||
|
end_time: "",
|
||||||
|
is_sashier: 2, // 1-收银订单, 2-小程序订单
|
||||||
|
});
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
|
const total = ref(0);
|
||||||
|
const activeStore = ref(0);
|
||||||
|
|
||||||
|
const loadEnd = ref(false);
|
||||||
|
const orderList = ref([]);
|
||||||
|
const getOrderList = (reload = false) => {
|
||||||
|
if (reload) where.value.page_no = 1;
|
||||||
|
else if (loadEnd.value || loading.value) return;
|
||||||
|
loading.value = true;
|
||||||
|
userListsApi(where.value)
|
||||||
|
.then((res) => {
|
||||||
|
if (reload) orderList.value = res.data.lists;
|
||||||
|
else orderList.value = [...orderList.value, ...res.data.lists];
|
||||||
|
if (where.value.page_no == 1 && orderList.value.length > 0) mitt.emit("set-user-detail", orderList.value[0]);
|
||||||
|
if (res.data.lists.length < where.value.page_size) loadEnd.value = true;
|
||||||
|
else where.value.page_no++;
|
||||||
|
activeStore.value = 0;
|
||||||
|
total.value = res.data.count;
|
||||||
|
loading.value = false;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
loadEnd.value = true;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const setForm = (item, index) => {
|
||||||
|
activeStore.value = index;
|
||||||
|
mitt.emit("set-user-detail", item);
|
||||||
|
};
|
||||||
|
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const addRef = ref(null);
|
||||||
|
const addUser = ()=>{
|
||||||
|
addRef.value?.addUser();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="my-order">
|
||||||
|
<div class="header-nav">
|
||||||
|
<div class="nav-item">
|
||||||
|
{{ "用户列表" }}
|
||||||
|
</div>
|
||||||
|
<el-button type="primary" @click="dialogVisible = true"><el-icon>
|
||||||
|
<Plus />
|
||||||
|
</el-icon> 添加用户</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="header-input">
|
||||||
|
<el-input v-model="where.order_id" placeholder="搜索手机号/ID" @keydown.enter="getOrderList(true)"
|
||||||
|
@clear="getOrderList(true)" clearable>
|
||||||
|
<template #append>
|
||||||
|
<el-button type="primary" style="
|
||||||
|
background-color: #1890ff;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 0 0.315rem 0.315rem 0;
|
||||||
|
" @click="getOrderList(true)">搜索</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
<div class="order-lists" v-loading="loading" v-infinite-scroll="getOrderList" :infinite-scroll-distance="300"
|
||||||
|
:infinite-scroll-delay="500" style="overflow: auto">
|
||||||
|
<div class="item" :class="{ 'item-active': activeStore == index }" v-for="(item, index) in orderList"
|
||||||
|
:key="index" @click="setForm(item, index)">
|
||||||
|
<el-avatar class="avatar" :src="item.avatar" />
|
||||||
|
<div style="display: flex; flex-direction: column; justify-content: space-around;flex:1;">
|
||||||
|
<div class="top flex">
|
||||||
|
<div class="r-1"><span class="bold">{{ item.nickname }}</span><span>{{ ' (ID:' + item.id +')'}}</span></div>
|
||||||
|
<div>手机号: {{ item.mobile }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="bottom flex" style="justify-content: space-between;">
|
||||||
|
<!-- <div class="r-1">积分: <span class="red">55</span></div> -->
|
||||||
|
<div>余额: <span class="red">{{item.user_money}}</span></div>
|
||||||
|
<div>
|
||||||
|
<el-tag type="primary" v-if="item.user_ship==0">{{ item.user_ship_name }}</el-tag>
|
||||||
|
<el-tag type="success" v-else>{{ item.user_ship_name }}</el-tag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="loadEnd" class="load-end">没有更多了</div>
|
||||||
|
<div v-if="loading" class="load-end">加载中...</div>
|
||||||
|
</div>
|
||||||
|
<el-dialog v-model="dialogVisible" title="添加用户" width="600">
|
||||||
|
<add ref="addRef" @close="dialogVisible = false"></add>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="addUser">
|
||||||
|
添加
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.my-order {
|
||||||
|
border-radius: 1.2rem;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
width: 30rem;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.header-nav {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 1rem;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #ff4a00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-input {
|
||||||
|
padding: 1rem;
|
||||||
|
padding-top: 0;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-lists {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
padding: 1rem;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
height: 4rem;
|
||||||
|
width: 4rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 1rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bold{
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.r-1{
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom {
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: #ff4a00;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-active {
|
||||||
|
background-color: #efefef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.load-end {
|
||||||
|
text-align: center;
|
||||||
|
padding: 1rem;
|
||||||
|
color: #333;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,43 @@
|
||||||
|
<script setup>
|
||||||
|
import order from "./component/order.vue";
|
||||||
|
import detail from "./component/detail.vue";
|
||||||
|
import padding from "@/components/padding.vue";
|
||||||
|
import { ref, nextTick } from "vue";
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="my-card">
|
||||||
|
<order style="flex-shrink: 0;" ref="orderRef"/>
|
||||||
|
<padding />
|
||||||
|
<detail ref="detailRef"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.my-card {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
/* 修改滚动条的样式 */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 0.315rem; /* 设置滚动条的宽度 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 设置滚动条的轨道样式 */
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background-color: #f1f1f1; /* 设置轨道的背景色 */
|
||||||
|
/* margin: 1.25rem 0; */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 设置滚动条的滑块样式 */
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #ccc; /* 设置滑块的背景色 */
|
||||||
|
border-radius: 0.315rem; /* 设置滑块的圆角 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 设置滚动条鼠标悬停时的滑块样式 */
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background-color: #999; /* 设置鼠标悬停时滑块的背景色 */
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue