This commit is contained in:
weipengfei 2024-06-14 18:26:43 +08:00
parent 25be510191
commit 0613c96862
16 changed files with 896 additions and 108 deletions

View File

@ -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'

31
src/api/public.js Normal file
View File

@ -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 })
}

View File

@ -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 })
} }

View File

@ -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`)
}

View File

@ -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;

View File

@ -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 },

View File

@ -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',

View File

@ -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";

86
src/utils/axiosAPI.js Normal file
View File

@ -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;

View File

@ -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>

View File

@ -1,133 +1,166 @@
<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 getCategoryList = () => { const userStore = useUserStore();
merchantCategoryListApi().then((res) => {
categoryList.value = res.data.lists;
active.value = -1;
});
};
// getCategoryList();
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; sactive.value = index;
active.value = index; show.value = true;
cactive.value = idnexc; let cate_id = '';
console.log(index, idnexc); let class_all = '';
show.value = true; if (type == 1) {
let mer_cate_id = ''; active.value = index;
if(index>=0 &&idnexc>=0) mer_cate_id = categoryList.value[index].children[idnexc].store_category_id; cactive.value = -1;
else if(index>=0) mer_cate_id = categoryList.value[index].store_category_id; dactive.value = -1;
emit("getStoreList", { if (index!=-1) class_all = categoryList.value[index].id;
mer_cate_id: mer_cate_id, getCategoryList2(class_all);
}, true); }
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> </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" <template #reference>
trigger="click" <div class="itemP" :class="{ 'itemP-active': index == active }" @click="changeActive(index)"
v-for="(item, index) in categoryList" @mousemove="sactive = index">
:key="index" {{ item.name }}
:visible="index==active && sactive==index" </div>
> </template>
<template #reference> <div class="active-card" @mouseout="sactive = -1" @mousemove="sactive = index">
<div <div class="title">{{ item.name }}</div>
class="itemP" <div class="list">
:class="{ 'itemP-active': index == active }" <div :class="{ 'list-active': indexc == cactive }" link type="primary"
@click="changeActive(index)" v-for="(chil, indexc) in categoryList2" :key="chil.id" @click="changeActive(indexc, 2)">
@mousemove="sactive=index" {{ chil.name }}
> </div>
{{ item.name }} </div>
</div> </div>
</template> </el-popover>
<div class="active-card" </div>
@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>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.classify { .classify {
height: 100%; height: 100%;
width: 8rem; width: 8rem;
background-color: #fff; background-color: #fff;
border-radius: 1.2rem; border-radius: 1.2rem;
font-size: 1rem; font-size: 1rem;
color: #333; color: #333;
overflow-y: scroll; overflow-y: scroll;
.itemP { .itemP {
width: 4rem; width: 4rem;
margin: 1rem; margin: 1rem;
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
text-align: center; text-align: center;
border-radius: 3rem; border-radius: 3rem;
cursor: pointer; cursor: pointer;
white-space: nowrap; /* 防止文本换行 */ white-space: nowrap;
overflow: hidden; /* 防止文本换行 */
text-overflow: ellipsis; /* 多余文本使用省略号显示 */ overflow: hidden;
} text-overflow: ellipsis;
.itemP-active { /* 多余文本使用省略号显示 */
background-color: #1890ff; }
color: #fff;
} .itemP-active {
background-color: #1890ff;
color: #fff;
}
} }
.active-card { .active-card {
.title { .title {
font-size: 1.1rem; font-size: 1.1rem;
font-weight: bold; font-weight: bold;
color: #333; color: #333;
}
.list {
display: flex;
div {
margin-right: 1rem;
margin-top: 0.5rem;
cursor: pointer;
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 { ::-webkit-scrollbar {
display: none; display: none;
} }
</style> </style>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

43
src/views/user/index.vue Normal file
View File

@ -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>