This commit is contained in:
weipengfei 2023-12-05 18:39:17 +08:00
parent 3c361aef23
commit 2885e6faea
27 changed files with 788 additions and 257 deletions

View File

@ -1,16 +1,8 @@
<script setup>
import headView from "@/components/headView.vue";
import Businesses from "@/components/Businesses.vue";
</script>
<template>
<dv-full-screen-container class="body">
<headView></headView>
<div style="height: calc(100% - 60px)">
<router-view></router-view>
</div>
<Businesses class="businesses"></Businesses>
</dv-full-screen-container>
<router-view></router-view>
</template>
<style scoped lang="scss">
@ -18,20 +10,4 @@ import Businesses from "@/components/Businesses.vue";
margin: 0;
padding: 0;
}
.body {
background-image: url("/src/assets/img/bg.png");
background-size: 100% 100%;
color: #fff;
background-color: rgba($color: #000000, $alpha: 0.8);
}
.businesses {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 999999;
width: 100%;
height: 100%;
}
</style>

35
src/api/api.js Normal file
View File

@ -0,0 +1,35 @@
import axios from "axios";
const instacne = axios.create({
baseURL: "http://192.168.1.15:9527/",
timeout: 30000,
});
instacne.interceptors.request.use(
(config) => {
return config;
},
(err) => {
return Promise.reject(err);
}
);
instacne.interceptors.response.use(
(res) => {
return res.data;
},
(err) => {
return Promise.reject(err);
}
);
export function loginAPI (parms) {
return instacne.post('/login', parms)
}

View File

@ -1,26 +1,46 @@
import axios from "@/utils/axios.js";
// 获取街道
export const getStreet = (data) => {
return axios.get('city/get_street', { params: data });
}
// 订单列表
export const orderList = (data) => {
return axios.get('dataview/curr_order_info', { params: data });
}
// 订单排行
export const orderRanking = (data) => {
return axios.get('dataview/order_ranking', { params: data });
}
// 配送商品排行
export const deliveredProductRanking = (data) => {
return axios.get('dataview/delivered_product_ranking', { params: data });
}
// 三轮车列表
export const vehicleList = (data) => {
return axios.get('dataview/vehicle_list', { params: data });
}
// 配送详情
export const latestLogistics = (data) => {
return axios.get('dataview/latest_logistics', { params: data });
}
// 物流信息
export const logisticsCount = (data) => {
return axios.get('dataview/logistics_count', { params: data });
}
// 条状图统计信息
export const dateCangeCrderCount = (data) => {
return axios.get('dataview/date_range_order_count', { params: data });
}
// 地图配送信息
export const logisticsMapCount = (data) => {
return axios.get('dataview/logistics_map_count', { params: data });
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/assets/login_img/DL.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

BIN
src/assets/login_img/KJ.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
src/assets/login_img/MM.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
src/assets/login_img/ZH.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
src/assets/login_img/bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -5,6 +5,10 @@ import { useRouter } from 'vue-router'
import paging from "./paging.vue"
import mitt from "@/utils/mitt"
import { orderList } from "@/api/index.js"
import { useAppStore } from "@/store/app.js"
const appStore = useAppStore();
const route = useRouter()
const ShwostoreType = ref(false)
@ -69,8 +73,8 @@ const configs = reactive({
})
const pages = ref({
areaCode: 510524,
streetCode: 510524100,
areaCode: appStore.address.areaCode,
streetCode: appStore.address.streetCode,
page: 1,
limit: 30,
total: 0,

View File

@ -49,7 +49,6 @@ const appStore = useAppStore();
//
const choseTownFn = (item) => {
emit('offAreaList', item);
if (item.code.length == 6) {
appStore.setMapInfo('luxian');
appStore.setAddress({
@ -62,6 +61,7 @@ const choseTownFn = (item) => {
streetCode: item.code
})
}
emit('offAreaList', item);
}
const open = () => {

View File

@ -1,11 +1,13 @@
<script setup>
import { reactive, ref, provide, nextTick, onMounted } from "vue";
import { reactive, ref, provide, nextTick, onMounted, inject } from "vue";
import areaList from "./areaList.vue";
import { useRoute, useRouter } from "vue-router";
import mitt from "@/utils/mitt";
import { getStreet } from "@/api/index.js"
import { useAppStore } from "@/store/app.js";
const reload = inject('reload');
const info = reactive({
address: '泸县',
pinyin: 'luxian'
@ -29,6 +31,7 @@ const offAreaList = (e) => {
})
info.address = e.name;
mitt.emit('map_info', info);
reload();
}
const list = ref([])

66
src/layout/index.vue Normal file
View File

@ -0,0 +1,66 @@
<script setup>
import headView from "@/components/headView.vue";
import Businesses from "@/components/Businesses.vue";
import { ref, nextTick, provide, onMounted, onUnmounted } from "vue";
const show = ref(true);
const reload = () => {
show.value = false;
nextTick(() => {
show.value = true;
})
}
provide('reload', reload);
//
let timer = null;
const startReLoad = () => {
clearInterval(timer);
timer = setInterval(() => {
reload();
}, 3 * 60 * 1000);
}
onMounted(() => {
startReLoad();
window.addEventListener('mousemove', startReLoad);
window.addEventListener('keypress', startReLoad);
window.addEventListener('click', startReLoad);
})
onUnmounted(() => {
window.removeEventListener('mousemove', startReLoad);
window.removeEventListener('keypress', startReLoad);
window.removeEventListener('click', startReLoad);
})
</script>
<template>
<dv-full-screen-container class="body">
<headView></headView>
<div style="height: calc(100% - 60px)">
<router-view v-if="show"></router-view>
</div>
<Businesses class="businesses"></Businesses>
</dv-full-screen-container>
</template>
<style scoped lang="scss">
.body {
background-image: url("/src/assets/img/bg.png");
background-size: 100% 100%;
color: #fff;
background-color: rgba($color: #000000, $alpha: 0.8);
}
.businesses {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 999999;
width: 100%;
height: 100%;
}
</style>

View File

@ -4,12 +4,24 @@ const routes = [
{
path: '/',
name: 'index',
component: () => import('../view/index/index.vue')
component: () => import('../layout/index.vue'),
children: [
{
path: '/',
name: '',
component: () => import('../view/index/index.vue')
},
{
path: '/delivery',
name: 'delivery',
component: () => import('../view/delivery/index.vue')
},
]
},
{
path: '/delivery',
name: 'delivery',
component: () => import('../view/delivery/index.vue')
path: '/login',
name: '/login',
component: () => import('../view/login/index.vue')
}
]

View File

@ -4,26 +4,58 @@ import { ref } from "vue"
export const useAppStore = defineStore('app', () => {
const map_info = ref(localStorage.getItem('map_info') || 'luxian');
const address = ref(JSON.parse(localStorage.getItem('address') || '{}'));
if (!address.value.areaCode) {
address.value = { areaCode: 510521, streetCode: 510521100 };
}
const setMapInfo = (e) => {
map_info.value = e;
localStorage.setItem('map_info', e);
}
const address = ref(JSON.parse(localStorage.getItem('address') || '{}'));
if (!address.value.areaCode) {
address.value = { areaCode: 510524, streetCode: 510524100 };
}
// 测试使用的初始化配置
address.value = { areaCode: 510524, streetCode: 510524100 };
const setAddress = (e) => {
address.value.areaCode = e.areaCode;
address.value.streetCode = e.streetCode;
e.areaCode ? address.value.areaCode = e.areaCode : null;
e.streetCode ? address.value.streetCode = e.streetCode : null;
localStorage.setItem('address', JSON.stringify(e));
}
const delivery = ref({
pending_order_count: 0,
delivering_order_count: 0,
finished_order_count: 0,
order_count: 0
})
const setDelivery = (e) => {
e.pending_order_count ? delivery.value.pending_order_count = e.pending_order_count : null;
e.delivering_order_count ? delivery.value.delivering_order_count = e.delivering_order_count : null;
e.finished_order_count ? delivery.value.finished_order_count = e.finished_order_count : null;
e.order_count ? delivery.value.order_count = e.order_count : null;
}
const delivery_address = ref(JSON.parse(localStorage.getItem('delivery_address') || '{}'));
if (!delivery_address.value.areaCode) {
delivery_address.value = { areaCode: 510524, streetCode: 510524100 };
}
const setDeliveryAddress = (e) => {
delivery_address.value = e;
localStorage.setItem('delivery_address', JSON.stringify(e));
}
return {
map_info,
address,
delivery,
delivery_address,
setMapInfo,
setAddress
setAddress,
setDelivery,
setDeliveryAddress
}
})

View File

@ -6,11 +6,18 @@ let map = null;
const loading = ref(true);
onMounted(() => {
const props = defineProps({
info: {
type: Object,
default: () => { }
}
})
const initMap = () => {
AMapLoader.load({
key: "4f8f55618010007147aab96fc72bb408", // WebKey load
version: "2.0", // JSAPI 1.4.15
plugins: ['AMap.ToolBar', 'AMap.Driving', 'AMap.AutoComplete'] // 使'AMap.Scale'
plugins: ['AMap.ToolBar', 'AMap.Driving', 'AMap.AutoComplete', 'AMap.Geocoder'] // 使'AMap.Scale'
})
.then((AMap) => {
map = new AMap.Map("container-left", {
@ -28,6 +35,7 @@ onMounted(() => {
loading.value = false;
}, 500)
});
const driving = new AMap.Driving({
map: map,
// 线AMap.DrivingPolicy.LEAST_TIME
@ -37,20 +45,59 @@ onMounted(() => {
showTraffic: false, //
// autoFitView: false //
})
const points = [
{ keyword: '莲花池街道里海科技', city: '泸州' },
{ keyword: '万象汇', city: '泸州' }
]
driving.search(points, (status, result) => {
// result线
console.log('status=', status)
console.log('result=', result)
})
let str = props.info.user_address;
str = str.replace(/[1-10]队/, '');
if (props.info.mer_lat && props.info.mer_long) {
let geocoder = new AMap.Geocoder({
city: "泸州"
});
geocoder.getLocation(str, function (status, result) {
if (status === 'complete' && result.info === 'OK') {
//
var geocode = result.geocodes[0];
let start = [props.info.mer_long, props.info.mer_lat];
let end = [geocode.location.lng, geocode.location.lat];
driving.search(start, end, (status, result) => {
// result线
// console.log('status=', status)
console.log('result=', result)
})
} else {
//
const points = [
{ keyword: props.info.mer_address, city: '泸州' },
{ keyword: str, city: '泸州' }
];
driving.search(points, (status, result) => {
// result线
// console.log('status=', status)
console.log('result=', result)
})
}
});
} else {
const points = [
{ keyword: props.info.mer_address, city: '泸州' },
{ keyword: str, city: '泸州' }
];
driving.search(points, (status, result) => {
// result线
// console.log('status=', status)
console.log('result=', result)
})
}
})
.catch((e) => {
console.log(e);
});
}
onMounted(() => {
initMap();
});
onUnmounted(() => {

View File

@ -1,39 +1,38 @@
<script setup>
import { onMounted, reactive, ref } from "vue"
import { onMounted, reactive, ref, watch } from "vue"
import border from "@/components/border.vue";
import * as echarts from 'echarts';
import mitt from "@/utils/mitt"
import mitt from "@/utils/mitt";
import { dateCangeCrderCount, orderList as getOrderList } from "@/api/index.js";
import { useAppStore } from "@/store/app.js";
const initData = (aaa) => {
for (let i = 0; i < 20; i++) {
if (i % 2 == 0) {
aaa.data.push(
[
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: rgba(91, 219, 246, 0.20)'>排序</div>`,
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: rgba(91, 219, 246, 0.20)' >排sd序</div>`,
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: rgba(91, 219, 246, 0.20)'>排序</div>`,
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: rgba(91, 219, 246, 0.20)'>排序</div>`,
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: rgba(91, 219, 246, 0.20)'>排序</div>`,
]
)
} else {
aaa.data.push(
[
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: rgba(0, 168, 255, 0.16)'>排序</div>`,
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: rgba(0, 168, 255, 0.16)' >排sd序</div>`,
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: rgba(0, 168, 255, 0.16)'>排序</div>`,
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: rgba(0, 168, 255, 0.16)'>排序</div>`,
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: rgba(0, 168, 255, 0.16)'>排序</div>`,
]
)
const appStore = useAppStore();
const scrollBoardRef = ref(null);
const initData = (data) => {
let arr = [];
for (let i = 0; i < data.length; i++) {
let calss = 'div';
if (i % 2 != 0) {
calss = 'div div2'
}
arr.push(
[
`<div class="${calss}">${i + 1}</div>`,
`<div class="${calss}">${data[i].real_name || '-'}</div>`,
`<div class="${calss}">${data[i].user_phone || '-'}</div>`,
`<div class="${calss}">${data[i].store_name || '-'}</div>`,
`<div class="${calss}">${data[i].user_address || '-'}</div>`,
]
)
}
list.data = arr;
scrollBoardRef.value?.updateRows(list.data);
}
const list = reactive({
header: [
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: linear-gradient(rgba(0, 168, 255, 0.76), rgba(0, 84, 128, 0.73));'>ID</div>`,
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: linear-gradient(rgba(0, 168, 255, 0.76), rgba(0, 84, 128, 0.73));'>序号</div>`,
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: linear-gradient(rgba(0, 168, 255, 0.76), rgba(0, 84, 128, 0.73));'>收货人</div>`,
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: linear-gradient(rgba(0, 168, 255, 0.76), rgba(0, 84, 128, 0.73));'>收货人电话</div>`,
`<div style='width: 100%;text-align: center; height: 100%; color: aliceblue; background: linear-gradient(rgba(0, 168, 255, 0.76), rgba(0, 84, 128, 0.73));'>商品名称</div>`,
@ -46,32 +45,39 @@ const list = reactive({
// evenRowBGC: 'rgba(0, 168, 255, 0.16)',
oddRowBGC: '',
evenRowBGC: "",
// columnWidth: [50],
columnWidth: [40, 80],
align: ['center'],
rowNum: 7
})
initData(list);
const orderList = reactive([
const orderList = ref([
{
name: '今日订单',
value: '988'
value: '0'
},
{
name: '取货订单',
value: '1523'
name: '取货订单',
value: '0'
},
{
name: '配送订单',
value: '55'
name: '配送订单',
value: '0'
},
{
name: '已完成订单',
value: '3'
value: '0'
},
])
watch(() => appStore.delivery, (n, o) => {
orderList.value[0].value = n.order_count;
orderList.value[1].value = n.pending_order_count;
orderList.value[2].value = n.delivering_order_count;
orderList.value[3].value = n.finished_order_count;
}, { deep: true, immediate: true })
const cOrderValue = (e) => {
let str = e;
if (str > 9999) str = 9999 + '';
@ -87,18 +93,16 @@ const cOrderValue = (e) => {
return str;
}
const echartsRef = ref(null)
const initEcahrts = () => {
let xData = ['09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00'],
yData1 = [400, 410, 350, 320, 280, 340, 360, 400, 420, 410],
yData2 = [350, 320, 260, 240, 220, 280, 300, 360, 340, 340],
yData3 = [200, 260, 200, 190, 180, 220, 260, 300, 280, 300],
yData4 = [120, 300, 230, 240, 190, 290, 103, 456, 230, 270],
const initEcahrts = (yData1 = [], yData2 = [], yData3 = [], yData4 = []) => {
let xData = ['00:00', '02:00', '04:00', '06:00', '08:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00'],
// yData1 = [400, 410, 350, 320, 280, 340, 360, 400, 420, 410],
// yData2 = [350, 320, 260, 240, 220, 280, 300, 360, 340, 340],
// yData3 = [200, 260, 200, 190, 180, 220, 260, 300, 280, 300],
// yData4 = [120, 300, 230, 240, 190, 290, 103, 456, 230, 270],
borderData = [],
legend = ["已取货订单", "未配送订单", "已完成订单", "小时订单数"],
legend = ["未取货订单", "配送中订单", "已完成订单", "小时订单数"],
colorArr = [{
start: "rgba(0, 168, 255,",
end: "rgba(0, 168, 255, 1)"
@ -356,8 +360,41 @@ const openList = () => {
mitt.emit('showBusinesses')
}
const initInfo = () => {
dateCangeCrderCount({
areaCode: appStore.delivery_address.areaCode,
streetCode: appStore.delivery_address.streetCode,
}).then(({ data }) => {
let y1 = [], y2 = [], y3 = [], y4 = [];
data.forEach((item) => {
y1.push(item.pendingOrderCount);
y2.push(item.undeliveredOrderCount);
y3.push(item.doneOrderCount);
y4.push(item.hourOrderCount);
})
setTimeout(() => {
initEcahrts(y1, y2, y3, y4);
})
})
}
const pages = ref({
areaCode: appStore.delivery_address.areaCode,
streetCode: appStore.delivery_address.streetCode,
page: 1,
limit: 30
})
const loadOrderList = () => {
getOrderList(pages.value).then((res) => {
initData(res.data.currOrderList);
}).catch(err => {
console.error(err);
})
}
onMounted(() => {
initEcahrts()
initInfo();
loadOrderList();
})
</script>
@ -391,7 +428,11 @@ onMounted(() => {
<div>{{ "〉" }}</div>
</div>
</div>
<dv-scroll-board :config="list" style="width: 100%; height: 90%" />
<dv-scroll-board
ref="scrollBoardRef"
:config="list"
style="width: 100%; height: 90%"
/>
</div>
</div>
</div>
@ -493,6 +534,21 @@ onMounted(() => {
}
}
:deep(.div) {
width: 100%;
text-align: center;
height: 100%;
color: aliceblue;
background: rgba(91, 219, 246, 0.2);
white-space: nowrap; /* 防止文本换行 */
overflow: hidden; /* 溢出部分隐藏 */
text-overflow: ellipsis; /* 显示省略号 */
}
:deep(.div2) {
background: rgba(0, 168, 255, 0.16);
}
:deep(.ceil) {
padding: 0 !important;
margin-bottom: 5px;

View File

@ -1,11 +1,30 @@
<script setup>
import { reactive, ref } from "vue"
import { onMounted, reactive, ref } from "vue"
import border from "@/components/border.vue";
import AMap from "./AMap.vue";
import { useAppStore } from "@/store/app.js"
import { logisticsMapCount } from "@/api/index.js";
const test = () => {
console.log('ss');
const appStore = useAppStore();
const initInfo = () => {
logisticsMapCount({
areaCode: appStore.delivery_address.areaCode,
streetCode: appStore.delivery_address.streetCode,
courier_id: appStore.delivery_address.courier_id
}).then(res => {
console.log(res);
})
}
const clickItem = () => {
console.log('点击按钮');
}
onMounted(() => {
initInfo()
})
</script>
<template>
@ -15,14 +34,20 @@ const test = () => {
</div>
<div class="border"></div>
<div class="btn">
<div class="c-b" @click.stop="test">
<div class="text">已取货(100)</div>
<div class="c-b" @click.stop="clickItem">
<div class="text">
待取货({{ appStore.delivery.pending_order_count }})
</div>
</div>
<div class="c-b" @click.stop="test">
<div class="text">已配送(100)</div>
<div class="c-b" @click.stop="clickItem">
<div class="text">
配送中({{ appStore.delivery.delivering_order_count }})
</div>
</div>
<div class="c-b" @click.stop="test">
<div class="text">已完成(100)</div>
<div class="c-b" @click.stop="clickItem">
<div class="text">
已完成({{ appStore.delivery.finished_order_count }})
</div>
</div>
</div>
</div>

View File

@ -5,137 +5,164 @@ import AMapLeft from "./AMapLeft.vue";
import * as echarts from 'echarts';
import { useRoute } from "vue-router"
import { latestLogistics } from "@/api/index.js";
import { logisticsCount } from "@/api/index.js";
import { useAppStore } from "@/store/app.js"
const appStore = useAppStore();
const route = useRoute();
let noramlSize = 16;
var datas = {
textValue: "100%",
const echartsRef = ref(null);
let datas = {
textValue: "",
colors: ["#31829d", "#009cff", "#4b5fdb"],
legendArr: ["待取货", "配送中", "已送达"],
dataArr: [
{ value: 335, name: "待取货" },
{ value: 210, name: "配送中" },
{ value: 410, name: "已送达" },
{ value: 0, name: "待取货" },
{ value: 0, name: "配送中" },
{ value: 0, name: "已送达" },
],
company: ""
company: ""
};
const option = {
backgroundColor: "rgba(0,0,0,0)",
color: datas.colors,
grid: {
left: "0%",
right: "0%",
bottom: "0%",
top: "0%"
},
graphic: {
elements: [
{
type: 'text',
left: 'center', //
bottom: '50%', //
style: {
fill: '#fff',
text: datas.textValue,
font: '18px Microsoft YaHei'
}
}
]
},
tooltip: {
trigger: "item",
backgroundColor: "#f6f6f6",
textStyle: {
color: "#000"
},
formatter: "{b}: {c}" + datas.company + " ({d}%)"
},
legend: {
icon: "rect",
bottom: "5%",
left: "center",
itemWidth: 12,
itemHeight: 12,
// itemGap: 50, //
textStyle: {
color: "#fff",
fontSize: noramlSize
},
data: datas.legendArr
},
series: [
{
name: "",
type: "pie",
radius: ["45%", "60%"],
center: ["50%", "45%"],
itemStyle: {
normal: {
borderWidth: 10,
borderColor: "#092846"
}
},
avoidLabelOverlap: false,
label: {
show: false,
position: 'bottom'
},
labelLine: {
normal: {
show: true,
lineStyle: {
color: "#138af4"
},
length: 20,
length2: 50,
}
},
data: datas.dataArr
},
{
type: "pie",
radius: "40%",
center: ["50%", "45%"],
z: -2,
label: {
show: false
},
labelLine: {
show: false
},
itemStyle: {
color: 'rgba(255,255,255,0.2)'
},
data: [100]
},
]
};
const echartsRef = ref(null)
const initEcahrts = () => {
// DOMecharts
const chart = echarts.init(echartsRef.value);
let option = {
backgroundColor: "rgba(0,0,0,0)",
color: datas.colors,
grid: {
left: "0%",
right: "0%",
bottom: "0%",
top: "0%"
},
graphic: {
elements: [
{
type: 'text',
left: 'center', //
bottom: '50%', //
style: {
fill: '#fff',
text: datas.textValue,
font: '18px Microsoft YaHei'
}
}
]
},
tooltip: {
trigger: "item",
backgroundColor: 'rgba(18, 57, 60, .8)', //
textStyle: {
color: '#fff'
},
borderColor: "rgba(18, 57, 60, .8)",
axisPointer: {
type: 'shadow',
shadowStyle: {
color: 'rgba(0, 11, 34, .4)',
}
},
formatter: "{b}: {c}" + datas.company + " ({d}%)"
},
legend: {
icon: "rect",
bottom: "5%",
left: "center",
itemWidth: 12,
itemHeight: 12,
// itemGap: 50, //
textStyle: {
color: "#fff",
fontSize: noramlSize
},
data: datas.legendArr
},
series: [
{
name: "",
type: "pie",
radius: ["45%", "60%"],
center: ["50%", "45%"],
itemStyle: {
normal: {
borderWidth: 10,
borderColor: "#092846"
}
},
avoidLabelOverlap: false,
label: {
show: false,
position: 'bottom'
},
labelLine: {
normal: {
show: true,
lineStyle: {
color: "#138af4"
},
length: 20,
length2: 50,
}
},
data: datas.dataArr
},
{
type: "pie",
radius: "40%",
center: ["50%", "45%"],
z: -2,
tooltip: {
show: false
},
label: {
show: false
},
labelLine: {
show: false
},
itemStyle: {
color: 'rgba(255,255,255,0.2)'
},
data: [100]
},
]
};
// 使
chart.setOption(option);
}
const info = ref({});
const delivery = ref({});
const loadInfo = () => {
latestLogistics({
areaCode: 510524,
streetCode: 510524100,
areaCode: appStore.delivery_address.areaCode,
streetCode: appStore.delivery_address.streetCode,
}).then(res => {
info.value = res.data;
})
logisticsCount({
areaCode: appStore.delivery_address.areaCode,
streetCode: appStore.delivery_address.streetCode
}).then(res => {
delivery.value = res.data;
datas.dataArr[0].value = res.data.pending_order_count;
datas.dataArr[1].value = res.data.delivering_order_count;
datas.dataArr[2].value = res.data.finished_order_count;
initEcahrts();
appStore.setDelivery(res.data);
})
}
onMounted(() => {
loadInfo();
initEcahrts();
})
</script>
@ -237,7 +264,7 @@ onMounted(() => {
</div>
</div>
<div class="map">
<AMapLeft></AMapLeft>
<AMapLeft :info="info" v-if="info.user_address"></AMapLeft>
<div class="border"></div>
</div>
<div class="head-box b-box">物流信息</div>
@ -245,11 +272,15 @@ onMounted(() => {
<div class="left">
<div class="left-item">
<img class="img" src="/src/assets/delivery_img/icon7.png" />
<div>配送人员<span>里斯</span></div>
<div>
配送人员<span>{{ delivery.courier_name || "-" }}</span>
</div>
</div>
<div class="left-item">
<img class="img" src="/src/assets/delivery_img/icon3.png" />
<div>配送车辆<span>川E G856Z</span></div>
<div>
配送车辆<span>{{ delivery.car_license || "-" }}</span>
</div>
</div>
</div>
<div class="right echarts" ref="echartsRef"></div>

View File

@ -1,31 +1,12 @@
<script setup>
import { nextTick, onMounted, onUnmounted, reactive, ref } from "vue"
import border from "../../../components/border.vue"
const items = reactive([
{ id: 1, text: '莲花池 1' },
{ id: 2, text: '莲花池 2' },
{ id: 3, text: '莲花池 3' },
{ id: 3, text: '莲花池 4' },
{ id: 3, text: '莲花池 5' },
{ id: 3, text: '莲花池 6' },
{ id: 3, text: '莲花池 7' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
{ id: 3, text: '莲花池 8' },
])
import { deliveredProductRanking } from "@/api/index.js"
import { useAppStore } from "@/store/app.js"
const appStore = useAppStore();
const items = ref([])
const scrollContainerRef = ref(null);
let timer = null;
const autoScroll = () => {
@ -42,7 +23,30 @@ const autoScroll = () => {
}, 50)
}, 1000)
}
const max = ref(0)
const loadList = () => {
deliveredProductRanking({
areaCode: appStore.address.areaCode,
streetCode: appStore.address.streetCode,
}).then((res) => {
items.value = res.data;
res.data.forEach(e => {
if (+e.total_quantity >= max.value) {
max.value = +e.total_quantity;
}
});
})
}
const cWidth = (e) => {
return (e / max.value * 100).toFixed(0);
}
onMounted(() => {
loadList();
nextTick(() => {
autoScroll();
})
@ -73,15 +77,17 @@ onUnmounted(() => {
<div class="rank" :class="index < 3 ? 'rank1' : 'rank2'">
{{ index + 1 }}
</div>
<div class="name">{{ item.text }}</div>
<div class="name">
<div>{{ item.store_name }}</div>
</div>
<div class="line">
<div
class="line-body"
:style="{ width: '80%' }"
:style="{ width: cWidth(item.total_quantity) + '%' }"
:class="{ 'line-body2': index >= 3 }"
></div>
</div>
<div class="count">6000</div>
<div class="count">{{ item.total_quantity }}</div>
</div>
</div>
</div>

View File

@ -3,6 +3,9 @@ import { onMounted, reactive, ref } from "vue";
import * as echarts from 'echarts';
import border from "../../../components/border.vue"
import { orderRanking } from "@/api/index.js"
import { useAppStore } from "@/store/app.js"
const appStore = useAppStore();
const xData2 = ref([]);
const data1 = ref([]);
@ -157,8 +160,8 @@ const initMap = () => {
const loadOrderList = () => {
orderRanking({
areaCode: '510524',
streetCode: '510524100',
areaCode: appStore.address.areaCode,
streetCode: appStore.address.streetCode,
type: 2, // 1, 2
}).then((res) => {
orderCount.value = res.data.orderCount;

View File

@ -3,6 +3,9 @@ import { onMounted, reactive, ref } from "vue"
import border from "@/components/border.vue"
import mitt from "@/utils/mitt"
import { orderList } from "@/api/index.js"
import { useAppStore } from "@/store/app.js"
const appStore = useAppStore();
const initData = (data) => {
let arr = [];
@ -106,8 +109,8 @@ const cOrder = () => {
}
const pages = ref({
areaCode: 510524,
streetCode: 510524100,
areaCode: appStore.address.areaCode,
streetCode: appStore.address.streetCode,
page: 1,
limit: 30
})
@ -177,7 +180,7 @@ onMounted(() => {
<div class="num">{{ cell[1].count }}</div>
</div>
<dv-percent-pond :config="cell[1]" class="cell" />
<div class="type">配送订单数</div>
<div class="type">配送订单数</div>
</div>
<div class="cy">
<div class="text">

View File

@ -2,6 +2,10 @@
import { nextTick, onMounted, onUnmounted, reactive, ref } from "vue"
import border from "../../../components/border.vue"
import { orderRanking } from "@/api/index.js"
import { useAppStore } from "@/store/app.js"
const appStore = useAppStore();
const items = ref([])
const scrollContainerRef = ref(null);
let timer = null;
@ -24,8 +28,8 @@ const max = ref(0);
const loadOrderList = () => {
orderRanking({
areaCode: '510524',
streetCode: '510524100',
areaCode: appStore.address.areaCode,
streetCode: appStore.address.streetCode,
type: 1, // 1, 2
}).then((res) => {
items.value = res.data.townOrderList;

View File

@ -3,14 +3,17 @@ import border from "@/components/border.vue"
import { vehicleList } from "@/api/index.js";
import { onMounted, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useAppStore } from "@/store/app.js"
const appStore = useAppStore();
const list = ref([])
const count = ref(0);
const loadList = () => {
vehicleList({
eaCode: '510524',
streetCode: '510524100',
areaCode: appStore.address.areaCode,
streetCode: appStore.address.streetCode,
}).then(res => {
list.value = res.data.list;
count.value = res.data.count;
@ -23,14 +26,16 @@ const loadList = () => {
const router = useRouter()
const route = useRoute()
const navToDelivery = (id) => {
if (route.path == '/') router.push({
const navToDelivery = (item) => {
item.areaCode = item.area_code;
item.streetCode = item.street_code;
appStore.setDeliveryAddress(item);
router.push({
path: '/delivery',
query: {
id
id: item.id
}
});
else router.back();
}
@ -59,7 +64,7 @@ onMounted(() => {
:class="{ 'car-item2': index > 1 }"
v-for="(item, index) in list.slice(0, 4)"
:key="index"
@click="navToDelivery(item.id)"
@click="navToDelivery(item)"
>
<img class="img" src="/src/assets/img/icon-car.png" />
<div>{{ item.license }}</div>
@ -81,7 +86,7 @@ onMounted(() => {
:class="{ 'car-item2': index > 2 && index < 5 }"
v-for="(item, index) in list.slice(4, 13)"
:key="index"
@click="navToDelivery(item.id)"
@click="navToDelivery(item)"
>
<img class="img" src="/src/assets/img/icon-car.png" />
<div>{{ item.license }}</div>

View File

@ -2,6 +2,9 @@
import { nextTick, onMounted, onUnmounted, reactive, ref } from "vue"
import border from "../../../components/border.vue"
import { deliveredProductRanking } from "@/api/index.js"
import { useAppStore } from "@/store/app.js"
const appStore = useAppStore();
const items = ref([]);
const max = ref(0);
@ -24,8 +27,8 @@ const autoScroll = () => {
const loadList = () => {
deliveredProductRanking({
areaCode: 510524,
streetCode: 510524100,
areaCode: appStore.address.areaCode,
streetCode: appStore.address.streetCode,
}).then((res) => {
items.value = res.data;
res.data.forEach(e => {

200
src/view/login/index.vue Normal file
View File

@ -0,0 +1,200 @@
<script setup>
import { ref, reactive } from "vue"
import { useRouter } from "vue-router";
import { loginAPI } from "@/api/api.js"
const router = useRouter()
const show = ref(false)
const account = ref('')
const password = ref('')
const isAccount = ref(false)
const isPassword = ref(false)
const submit = () => {
if (!account.value) {
isAccount.value = true;
return
}
else isAccount.value = false;
if (!password.value) {
isPassword.value = true;
return
}
else isPassword.value = false;
loginAPI({
account: account.value,
password: password.value
}).then(res => {
console.log(res);
// localStorage.setItem("TOKEN", 15455465465465)
// router.replace('/')
})
return
}
</script>
<template>
<dv-full-screen-container class="body">
<div class="login-box">
<div class="form">
<div class="content" style="padding-top: 2.5rem">
<div class="line-box">
<input
class="ipt"
type="text"
placeholder="请输入账号"
v-model="account"
/>
<div class="line">
<img
src="/src/assets/login_img/ZH.png"
alt=""
class="accont-icon"
/>
</div>
</div>
<div class="tips">
<span v-show="isAccount">请输入账号</span>
</div>
<div class="line-box">
<input
class="ipt"
placeholder="请输入密码"
:type="show ? 'text' : 'password'"
v-model="password"
/>
<div class="line">
<img
src="/src/assets/login_img/MM.png"
alt=""
class="accont-icon"
style=""
/>
<img
src="/src/assets/login_img/KJ.png"
v-if="show"
alt=""
@click="show = false"
class="accont-icon"
/>
<img
src="/src/assets/login_img/BKH.png"
v-else
@click="show = true"
class="accont-icon"
/>
</div>
</div>
<div class="tips">
<span v-show="isPassword">请输入密码</span>
</div>
<button class="btn" @click="submit">登录</button>
</div>
</div>
</div>
</dv-full-screen-container>
</template>
<style lang="scss" scoped>
.body {
background-image: url("/src/assets/img/bg.png");
background-size: 100% 100%;
color: #fff;
background-color: rgba($color: #000000, $alpha: 0.8);
}
.login-box {
width: 100%;
height: 100%;
background-image: url(../../assets/login_img/bg.png);
background-size: 100% 100%;
overflow: hidden;
}
.form {
width: 30%;
height: 45%;
position: absolute;
top: 25%;
right: 10%;
box-sizing: border-box;
background: url(../../assets/login_img/DLBG.png);
background-size: 100% 100%;
display: flex;
justify-content: center;
align-items: center;
.content {
width: 60%;
height: 60%;
.ipt {
border: 1px solid #194fa3;
background-color: #123266;
width: 100%;
box-sizing: border-box;
padding: 0.5rem 2.5rem;
outline: none;
-webkit-user-select: auto;
caret-color: #fff;
color: white;
}
.line-box {
position: relative;
width: 100%;
margin-top: 1rem;
.line {
width: 100%;
height: 100%;
position: absolute;
pointer-events: none;
top: 0;
left: 0;
display: flex;
justify-content: space-between;
padding: 0 0.5rem;
box-sizing: border-box;
align-items: center;
}
input {
font-size: 1rem;
}
}
input[type="password"]::-ms-reveal {
display: none;
}
.tips {
width: 100%;
height: 1.5rem;
margin-top: 0.3rem;
text-align: start;
color: red;
span {
margin-left: 2.5rem;
}
}
.btn {
width: 100%;
margin-top: 2rem;
background-color: #0040a1;
color: #fff;
border-radius: 0;
border: 0.1rem solid #2873ff;
}
.accont-icon {
width: 1rem;
height: 1rem;
pointer-events: all !important;
}
}
}
</style>