This commit is contained in:
parent
25be510191
commit
0613c96862
|
@ -1,10 +1,10 @@
|
|||
VITE_NOW_TYPE = 'dist'
|
||||
|
||||
# VITE_PUSH_URL = 'ws://192.168.1.22:8787'
|
||||
# VITE_BASE_URL = 'http://192.168.1.22:8545'
|
||||
VITE_PUSH_URL = 'ws://192.168.1.22:8787'
|
||||
VITE_BASE_URL = 'http://192.168.1.22:8545'
|
||||
|
||||
VITE_PUSH_URL ='wss://test-multi-store.lihaink.cn/pull'
|
||||
VITE_BASE_URL = 'https://test-multi-store.lihaink.cn'
|
||||
# VITE_PUSH_URL ='wss://test-multi-store.lihaink.cn/pull'
|
||||
# VITE_BASE_URL = 'https://test-multi-store.lihaink.cn'
|
||||
|
||||
# VITE_PUSH_URL ='wss://multi-store.lihaink.cn/pull'
|
||||
# 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 店铺商品分类
|
||||
*/
|
||||
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() {
|
||||
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 = {
|
||||
url: import.meta.env.VITE_BASE_URL + '/store',
|
||||
upload: import.meta.env.VITE_BASE_URL + '/store/upload/image/field',
|
||||
api: import.meta.env.VITE_BASE_URL + '/api',
|
||||
}
|
||||
|
||||
export default config;
|
|
@ -43,6 +43,7 @@ const newOrder = (e) => {
|
|||
} catch (error) {
|
||||
console.error(error);
|
||||
isPlaying = false;
|
||||
ElMessage.error('播放失败');
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -82,6 +83,12 @@ const list = ref([
|
|||
ico: "Van",
|
||||
count: 0,
|
||||
},
|
||||
{
|
||||
name: "user",
|
||||
title: "用户",
|
||||
ico: "User",
|
||||
count: 0,
|
||||
},
|
||||
// { name: "purchaseOrder", title: "采购订单", ico: "Van", count: 0 },
|
||||
// { name: "orderCount", title: "订单统计", ico: "DocumentRemove", count: 0 },
|
||||
// { name: "wallet", title: "余额提现", ico: "Wallet", count: 0 },
|
||||
|
|
|
@ -59,6 +59,12 @@ const routes = [
|
|||
meta: { title: '入库登记' },
|
||||
component: () => import('@/views/putStorage/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/user',
|
||||
name: 'user',
|
||||
meta: { title: '用户' },
|
||||
component: () => import('@/views/user/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/test',
|
||||
name: 'test',
|
||||
|
|
|
@ -116,7 +116,7 @@ export const printTicket = (obj = {}, test = false) => {
|
|||
if(!obj || !obj.order_id) obj = testObj;
|
||||
str += Esc.Size2(2) + Esc.Center() + Esc.boldFontOn() + obj.system_store_name + Esc.Size1() + "\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.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(() => {
|
||||
mitt.on("set-sale-order-detail", (res) => {
|
||||
console.log("===", res);
|
||||
|
@ -204,6 +209,11 @@ onUnmounted(() => {
|
|||
</el-table-column>
|
||||
</el-table>
|
||||
</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 v-else>
|
||||
<el-empty></el-empty>
|
||||
|
@ -221,13 +231,14 @@ onUnmounted(() => {
|
|||
overflow: hidden;
|
||||
|
||||
.detail {
|
||||
height: calc(100vh - 100px - 4rem);
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.table {
|
||||
padding: 1rem;
|
||||
padding-bottom: 6rem;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
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>
|
||||
|
|
|
@ -1,133 +1,166 @@
|
|||
<script setup>
|
||||
import { ref, watch, onMounted, onUnmounted, nextTick } from "vue";
|
||||
import { merchantCategoryListApi } from "@/api/shop.js";
|
||||
import { useUserStore } from '@/store/user.js'
|
||||
|
||||
const emit = defineEmits(["getStoreList"]);
|
||||
|
||||
const categoryList = ref([]);
|
||||
const categoryList2 = ref([]);
|
||||
const categoryList3 = ref([]);
|
||||
const active = ref(-1);
|
||||
const cactive = ref(-1);
|
||||
const dactive = ref(-1);
|
||||
const sactive = ref(-1);
|
||||
const show = ref(false);
|
||||
|
||||
const getCategoryList = () => {
|
||||
merchantCategoryListApi().then((res) => {
|
||||
categoryList.value = res.data.lists;
|
||||
active.value = -1;
|
||||
});
|
||||
};
|
||||
// getCategoryList();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const changeActive = (index=-1, idnexc=-1) => {
|
||||
const getCategoryList = () => {
|
||||
merchantCategoryListApi({
|
||||
pid: 0,
|
||||
page_no: 1,
|
||||
page_size: 30,
|
||||
level: 1,
|
||||
store_id: userStore.userInfo.store_id
|
||||
}).then((res) => {
|
||||
categoryList.value = res.data.lists;
|
||||
active.value = -1;
|
||||
});
|
||||
};
|
||||
getCategoryList();
|
||||
|
||||
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;
|
||||
active.value = index;
|
||||
cactive.value = idnexc;
|
||||
console.log(index, idnexc);
|
||||
show.value = true;
|
||||
let mer_cate_id = '';
|
||||
if(index>=0 &&idnexc>=0) mer_cate_id = categoryList.value[index].children[idnexc].store_category_id;
|
||||
else if(index>=0) mer_cate_id = categoryList.value[index].store_category_id;
|
||||
emit("getStoreList", {
|
||||
mer_cate_id: mer_cate_id,
|
||||
}, true);
|
||||
show.value = true;
|
||||
let cate_id = '';
|
||||
let class_all = '';
|
||||
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", {
|
||||
cate_id: cate_id,
|
||||
class_all: class_all
|
||||
}, true);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="classify" @mouseout="show?show=false:show=true">
|
||||
<div
|
||||
class="itemP"
|
||||
:class="{ 'itemP-active': -1 == active }"
|
||||
@click="changeActive(-1)"
|
||||
>
|
||||
{{ '全部' }}
|
||||
<div class="classify" @mouseout="show ? show = false : show = true">
|
||||
<div class="itemP" :class="{ 'itemP-active': -1 == active }" @click="changeActive(-1)">
|
||||
{{ '全部' }}
|
||||
</div>
|
||||
<el-popover
|
||||
placement="left"
|
||||
width="20rem"
|
||||
trigger="click"
|
||||
v-for="(item, index) in categoryList"
|
||||
:key="index"
|
||||
:visible="index==active && sactive==index"
|
||||
>
|
||||
<template #reference>
|
||||
<div
|
||||
class="itemP"
|
||||
:class="{ 'itemP-active': index == active }"
|
||||
@click="changeActive(index)"
|
||||
@mousemove="sactive=index"
|
||||
>
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</template>
|
||||
<div class="active-card"
|
||||
@mouseout="sactive=-1" @mousemove="sactive=index">
|
||||
<div class="title">{{ item.name }}</div>
|
||||
<div class="list">
|
||||
<div
|
||||
:class="{ 'list-active': indexc == cactive }"
|
||||
link
|
||||
type="primary"
|
||||
v-for="(chil, indexc) in item.children"
|
||||
:key="indexc"
|
||||
@click="changeActive(index, indexc)"
|
||||
>
|
||||
{{ chil.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
<el-popover placement="left" width="20rem" trigger="click" v-for="(item, index) in categoryList" :key="index"
|
||||
:visible="index == active && sactive == index">
|
||||
<template #reference>
|
||||
<div class="itemP" :class="{ 'itemP-active': index == active }" @click="changeActive(index)"
|
||||
@mousemove="sactive = index">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</template>
|
||||
<div class="active-card" @mouseout="sactive = -1" @mousemove="sactive = index">
|
||||
<div class="title">{{ item.name }}</div>
|
||||
<div class="list">
|
||||
<div :class="{ 'list-active': indexc == cactive }" link type="primary"
|
||||
v-for="(chil, indexc) in categoryList2" :key="chil.id" @click="changeActive(indexc, 2)">
|
||||
{{ chil.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.classify {
|
||||
height: 100%;
|
||||
width: 8rem;
|
||||
background-color: #fff;
|
||||
border-radius: 1.2rem;
|
||||
font-size: 1rem;
|
||||
color: #333;
|
||||
overflow-y: scroll;
|
||||
height: 100%;
|
||||
width: 8rem;
|
||||
background-color: #fff;
|
||||
border-radius: 1.2rem;
|
||||
font-size: 1rem;
|
||||
color: #333;
|
||||
overflow-y: scroll;
|
||||
|
||||
.itemP {
|
||||
width: 4rem;
|
||||
margin: 1rem;
|
||||
padding: 0.5rem 1rem;
|
||||
text-align: center;
|
||||
border-radius: 3rem;
|
||||
cursor: pointer;
|
||||
white-space: nowrap; /* 防止文本换行 */
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis; /* 多余文本使用省略号显示 */
|
||||
}
|
||||
.itemP-active {
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
}
|
||||
.itemP {
|
||||
width: 4rem;
|
||||
margin: 1rem;
|
||||
padding: 0.5rem 1rem;
|
||||
text-align: center;
|
||||
border-radius: 3rem;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
/* 防止文本换行 */
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/* 多余文本使用省略号显示 */
|
||||
}
|
||||
|
||||
.itemP-active {
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.active-card {
|
||||
.title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
.list {
|
||||
display: flex;
|
||||
div {
|
||||
margin-right: 1rem;
|
||||
margin-top: 0.5rem;
|
||||
cursor: pointer;
|
||||
color: #333;
|
||||
.title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
.list-active {
|
||||
color: #1890ff;
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
|
||||
div {
|
||||
margin-right: 1rem;
|
||||
margin-top: 0.5rem;
|
||||
cursor: pointer;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.list-active {
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 修改滚动条的样式 */
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -202,8 +202,8 @@ onUnmounted(() => {
|
|||
@loadMore="loadMore"
|
||||
/>
|
||||
<pupop ref="pupopRef" @changeItem="cartAddInfo" />
|
||||
<!-- <padding />
|
||||
<classify ref="classifyRef" @getStoreList="getStoreList"/> -->
|
||||
<padding />
|
||||
<classify ref="classifyRef" @getStoreList="getStoreList"/>
|
||||
<pay ref="payRef" @paySuccess="paySuccess" />
|
||||
</div>
|
||||
</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