This commit is contained in:
ChenQiuYu 2025-04-24 12:30:09 +08:00
parent e64b921719
commit 9d7947ef87
19 changed files with 1053 additions and 676 deletions

24
public/info/data.json Normal file
View File

@ -0,0 +1,24 @@
{
"systemMessage": [
{
"title":"系统通知",
"content":"欢迎使用",
"time":"2023-07-01 12:00:00"
},
{
"title":"系统通知",
"content":"欢迎使用",
"time":"2023-07-01 12:00:00"
},
{
"title":"系统通知",
"content":"欢迎使用",
"time":"2023-07-01 12:00:00"
}
],
"proxy": {
"name": "代理名称",
"qrCode": "qrCode.png",
"phone": "18888888888"
}
}

View File

@ -19,28 +19,11 @@ $border-color-extra-light: #F2F6FC;
// 背景颜色
$background-color-base: #eee;
$background-color-main: #5078c8;
$background-color-panel: #FFFFFF;
$background-color-b1:#E2E2E2;
// 字体大小
$font-size-extra-large: 20px;
$font-size-large: 18px;
$font-size-medium: 16px;
$font-size-base: 14px;
$font-size-small: 13px;
$font-size-extra-small: 12px;
// 边框圆角
$border-radius-base: 4px;
$border-radius-small: 2px;
$border-radius-large: 8px;
$border-radius-circle: 50%;
// 间距
$spacing-base: 8px;
$spacing-small: 4px;
$spacing-large: 16px;
$spacing-extra-large: 24px;
// 尺寸
$padding-base: 18px;
@ -48,11 +31,6 @@ $margin-base: 8px;
// 阴影
$box-shadow-base: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
$box-shadow-light: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
// 过渡
$transition-duration: 0.3s;
$transition-timing-function: ease-in-out;
// 布局
$header-height: 60px;
@ -92,24 +70,6 @@ $sidebar-collapse-width: 64px;
@mixin background-color {
background-color: $background-color-base;
}
@mixin background-color-panel {
background-color: $background-color-panel;
}
// 文字颜色混合器
@mixin text-color {
color: $text-primary;
}
// 边框颜色混合器
@mixin border{
border:1px solid $border-color-base;
}
// 字体大小混合器
@mixin font-size {
font-size: $font-size-base;
}
// 间距混合器
@mixin spacing{

View File

@ -15,8 +15,8 @@ ul, li {
html, body {
height: 100%;
font-family: PingFangSC, PingFang SC, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
font-size: base.$font-size-base;
font-family: Source Han Sans,PingFangSC, PingFang SC, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
font-size: 16px;
color: base.$text-primary;
background-color: base.$background-color-base;
-webkit-font-smoothing: antialiased;
@ -34,9 +34,7 @@ html {
}
body {
background-color: base.$background-color-base;
//font-family: Helvetica Neue, Helvetica, Arial, PingFang SC, MyHeiTi, Hiragino Sans GB, Heiti SC, WenQuanYi Micro Hei, sans-serif !important;
font-family: Source Han Sans, serif;
background-color: #EEEEEEFF;
}
.center-wrapper {
@ -71,7 +69,6 @@ body {
@include base.padding;
@include base.border-radius;
@include base.box-shadow;
@include base.background-color-panel;
margin-top: 10px;
min-height: 0;
}

View File

@ -36,23 +36,22 @@ const inputStr = (str: string) => {
</script>
<style scoped lang="scss">
@use "@/assets/scss/base.scss";
.code-popo{
width: 100%;
.code-item{
display: flex;
flex-wrap: wrap;
padding: 5px 0;
border-bottom: 1px solid base.$border-color-base;
border-bottom: 1px solid #fffeee;
.code-item-name{
flex: 0 0 calc(100% / 12);
font-size: base.$font-size-small;
font-size: 16px;
box-sizing: border-box;
padding: 5px;
text-align: center;
cursor: pointer;
&:hover{
color: base.$background-color-main;
color: #000;
}
}
}

View File

@ -26,11 +26,11 @@ const close = () => {
<transition name="el-fade-in">
<div class="mask" v-if="_isShow">
<div class="mask-wrapper" :style="{ width: _width + 'px', height: _height + 'px' }" v-if="_isShow">
<el-scrollbar height="100%">
<div class="header">
<div class="title">{{title}}</div>
<div class="close" @click="close"><el-icon><CloseBold/></el-icon></div>
</div>
<el-scrollbar height="100%">
<slot></slot>
</el-scrollbar>
</div>

View File

@ -0,0 +1,41 @@
<script setup lang="ts">
const imageList = [
{
image: '/static/images/home/banner.png'
},
{
image: '/static/images/home/banner1.png'
},
{
image: '/static/images/home/banner2.png'
},
{
image: '/static/images/home/banner3.png'
}
]
</script>
<template>
<div class="banner">
<el-carousel style="height: 100%">
<el-carousel-item v-for="(item,index) in imageList" :key="index">
<img class="image" :src="item.image" alt="">
</el-carousel-item>
</el-carousel>
</div>
</template>
<style scoped lang="scss">
.banner {
height: 154px;
background: #FFFFFF;
border-radius: 8px 8px 8px 8px;
margin-top: 24px;
.image {
width: 100%;
height: 100%;
border-radius: 8px 8px 8px 8px;
}
}
</style>

View File

@ -0,0 +1,102 @@
<script setup lang="ts">
import Panel from "@/components/common/Panel.vue";
import {onMounted, onUnmounted, ref} from "vue";
import * as echarts from "echarts";
import {getThisWeek} from "@/utils/dateUtils.ts";
import {post} from "@/utils/request.ts";
const echart = ref<HTMLElement | null>(null)
let myChart: echarts.ECharts | null = null;
onMounted(()=>{
initEcharts(dateList.value, vipData.value, commonData.value)
getPersonPayOverview()
window.addEventListener('resize', handleResize);
})
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
});
const handleResize = () => {
if (myChart) {
myChart.resize();
}
window.removeEventListener('resize', handleResize);
};
const getPersonPayOverview = () => {
const thisWeek = getThisWeek();
post("statistics/getPersonPayOverview", {beginTime: thisWeek.start, endTime: thisWeek.end}).then((res: any) => {
dateList.value = res.dateList
vipData.value = res.vipPrice
commonData.value = res.commonPrice
initEcharts(dateList.value, vipData.value, commonData.value)
})
}
const dateList = ref([
'2024-04-01',
'2024-03-30',
'2024-03-26',
'2024-03-22',
'2024-03-18',
'2024-03-14',
'2024-03-10',
'2024-03-06',
'2024-03-02',
])
const vipData = ref([120, 132, 101, 134, 90, 230, 210])
const commonData = ref([220, 182, 191, 234, 290, 330, 310])
const initEcharts = (dateList: any[], vipData: any, commonData: any) => {
if (myChart) {
myChart.dispose();
}
myChart = echarts.init(echart.value);
myChart.setOption(
{
title: {
text: ''
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['会员', '普通',]
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: true,
data: dateList
},
yAxis: {
type: 'value'
},
series: [
{
name: '会员',
type: 'line',
stack: 'Total',
data: vipData
},
{
name: '普通',
type: 'line',
stack: 'Total',
data: commonData
}
]
}
);
}
</script>
<template>
<Panel title="经营概况">
<div class="tu" ref="echart" style="height: 100%;width: 100%"></div>
</Panel>
</template>
<style scoped lang="scss">
</style>

View File

@ -1,5 +1,4 @@
<script setup lang="ts">
import Panel from "@/components/common/Panel.vue";
</script>
@ -24,5 +23,34 @@ import Panel from "@/components/common/Panel.vue";
</template>
<style scoped lang="scss">
.info {
height: 208px;
.info-content {
display: flex;
.image {
width: 88px;
height: 88px;
margin: 0 24px;
}
.app_info-content-text {
font-weight: 500;
font-size: 16px;
color: #333333;
font-style: normal;
.app_info-title {
max-width: 220px;
font-weight: bold;
font-size: 20px;
margin-bottom: 20px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
</style>

View File

@ -0,0 +1,46 @@
<script setup lang="ts">
import {defineModel} from 'vue'
import Panel from "@/components/common/Panel.vue";
const proxyMessage = defineModel<any>()
</script>
<template>
<Panel title="客服支持" class="service">
<div class="service-content">
<img class="image" src="/static/images/home/qr-code.png" alt="">
<div class="service-text">
<div style="margin-bottom: 20px">服务名称{{ proxyMessage.name }}</div>
<div>服务热线{{ proxyMessage.phone }}</div>
</div>
</div>
</Panel>
</template>
<style scoped lang="scss">
.service {
height: 170px;
margin: 24px 0;
padding-bottom: 24px;
.service-content {
display: flex;
.image {
width: 88px;
height: 88px;
margin: 0 24px;
}
.service-text {
font-weight: 500;
font-size: 16px;
color: #333333;
font-style: normal;
display: flex;
flex-direction: column;
justify-content: center;
}
}
}
</style>

View File

@ -0,0 +1,302 @@
<script setup lang="ts">
import Panel from "@/components/common/Panel.vue";
import InventoryWarnDetail from "@/components/home/index/Dialog/InventoryWarnDetail.vue";
import {nextTick, onMounted, ref} from "vue";
import {post} from "@/utils/request.ts";
onMounted(() => {
getInventoryWarning()
})
const inventoryWarnDetailRef = ref()
const inventoryWarnListSrc = ref<any>([]);
const inventoryWarnList = ref<any>([]);
const openInventoryWarnDetail = () => {
nextTick(() => {
inventoryWarnDetailRef.value.init(inventoryWarnListSrc.value)
})
}
const getInventoryWarning = () => {
post("statistics/numberEarlyWarning").then((res: any) => {
inventoryWarnListSrc.value = res
inventoryWarnList.value = res.slice(0, 3)
})
}
</script>
<template>
<Panel title="库存预警" class="kuCun">
<template #tools>
<el-button type="primary" size="small" @click="openInventoryWarnDetail">查看详情</el-button>
</template>
<div style="padding: 0 24px 24px">
<div class="box">
<div class="item" style="margin-right: 8px" v-if="inventoryWarnList[0]">
<img class="image" src="/static/images/home/1-danger.png" alt=""/>
<div class="item-content">
<el-tooltip
effect="dark"
:content="inventoryWarnList[0].name"
placement="bottom-start"
>
<div class="item-name">{{ inventoryWarnList[0].name }}</div>
</el-tooltip>
<div class="item-name-font">剩余库存值</div>
</div>
<div class="item-right">
<div class="wholeNumber">{{ inventoryWarnList[0].inventoryWholeNumber }}
<div class="item-right-num">{{ inventoryWarnList[0].packagingUnit }}</div>
</div>
<div class="wholeNumber" v-if="inventoryWarnList[0].inventoryFragmentNumber>0">
{{ inventoryWarnList[0].inventoryFragmentNumber }}
<div class="item-right-num" v-if="inventoryWarnList[0].inventoryFragmentNumber>0">
{{ inventoryWarnList[0].minPackagingUnit }}
</div>
</div>
</div>
</div>
<div class="item1" style="margin-right: 8px" v-if="inventoryWarnList[1]">
<img class="image" src="/static/images/home/1-danger.png" alt=""/>
<div class="item-content">
<el-tooltip
effect="dark"
:content="inventoryWarnList[1].name"
placement="bottom-start"
>
<div class="item-name">{{ inventoryWarnList[1].name }}</div>
</el-tooltip>
<div class="item-name-font">剩余库存值</div>
</div>
<div class="item-right">
<div class="wholeNumber">{{ inventoryWarnList[1].inventoryWholeNumber }}
<div class="item-right-num">{{ inventoryWarnList[1].packagingUnit }}</div>
</div>
<div class="wholeNumber" v-if="inventoryWarnList[1].inventoryFragmentNumber>0">
{{ inventoryWarnList[1].inventoryFragmentNumber }}
<div class="item-right-num" v-if="inventoryWarnList[1].inventoryFragmentNumber>0">
{{ inventoryWarnList[1].minPackagingUnit }}
</div>
</div>
</div>
</div>
<div class="item" style="margin-right: 8px" v-if="inventoryWarnList[2]">
<img class="image" src="/static/images/home/1-danger.png" alt=""/>
<div class="item-content">
<el-tooltip
effect="dark"
:content="inventoryWarnList[2].name"
placement="bottom-start"
>
<div class="item-name">{{ inventoryWarnList[2].name }}</div>
</el-tooltip>
<div class="item-name-font">剩余库存值</div>
</div>
<div class="item-right">
<div class="wholeNumber">{{ inventoryWarnList[2].inventoryWholeNumber }}
<div class="item-right-num">{{ inventoryWarnList[2].packagingUnit }}</div>
</div>
<div class="wholeNumber" v-if="inventoryWarnList[2].inventoryFragmentNumber>0">
{{ inventoryWarnList[2].inventoryFragmentNumber }}
<div class="item-right-num" v-if="inventoryWarnList[2].inventoryFragmentNumber>0">
{{ inventoryWarnList[2].minPackagingUnit }}
</div>
</div>
</div>
</div>
<div class="item1" style="margin-right: 8px" v-if="inventoryWarnList[3]">
<img class="image" src="/static/images/home/1-danger.png" alt=""/>
<div class="item-content">
<el-tooltip
effect="dark"
:content="inventoryWarnList[3].name"
placement="bottom-start"
>
<div class="item-name">{{ inventoryWarnList[3].name }}</div>
</el-tooltip>
<div class="item-name-font">剩余库存值</div>
</div>
<div class="item-right">
<div class="wholeNumber">{{ inventoryWarnList[3].inventoryWholeNumber }}
<div class="item-right-num">{{ inventoryWarnList[3].packagingUnit }}</div>
</div>
<div class="wholeNumber" v-if="inventoryWarnList[3].inventoryFragmentNumber>0">
{{ inventoryWarnList[3].inventoryFragmentNumber }}
<div class="item-right-num" v-if="inventoryWarnList[3].inventoryFragmentNumber>0">
{{ inventoryWarnList[3].minPackagingUnit }}
</div>
</div>
</div>
</div>
</div>
</div>
</Panel>
<InventoryWarnDetail ref="inventoryWarnDetailRef"></InventoryWarnDetail>
</template>
<style scoped lang="scss">
.kuCun {
height: 100%;
display: flex;
flex-direction: column;
margin-right: 24px;
.box {
.item {
float: left;
width:48%;
height: 58px;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: space-between;
flex: 1 1 calc(50% - 8px); //2 item item 33.33%
.image {
width: 34px;
height: 34px;
margin: 0 8px 0 16px;
}
.item-content {
flex: 1;
.item-name {
font-weight: 400;
font-size: 14px;
color: #333333;
font-style: normal;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item-name-font {
font-weight: 400;
font-size: 12px;
color: #999999;
font-style: normal;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.item-right {
width: 70px;
display: flex;
margin-right: 16px;
font-weight: bold;
font-style: normal;
font-size: 28px;
color: #FF282E;
align-items: flex-end;
.wholeNumber {
display: flex;
align-items: flex-end;
.item-right-num {
font-weight: 400;
font-size: 10px;
color: #333333;
font-style: normal;
padding-bottom: 3px;
}
}
}
&:nth-child(2n) {
margin-right: 0 !important;
}
&:nth-child(3) {
margin-top: 8px !important;
}
&:nth-child(4) {
margin-top: 8px !important;
}
}
.item1 {
float: right;
width:48%;
height: 58px;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: space-between;
flex: 1 1 calc(50% - 8px); //2 item item 33.33%
.image {
width: 34px;
height: 34px;
margin: 0 8px 0 16px;
}
.item-content {
flex: 1;
.item-name {
font-weight: 400;
font-size: 14px;
color: #333333;
font-style: normal;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item-name-font {
font-weight: 400;
font-size: 12px;
color: #999999;
font-style: normal;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.item-right {
width: 70px;
display: flex;
margin-right: 16px;
font-weight: bold;
font-style: normal;
font-size: 28px;
color: #FF282E;
align-items: flex-end;
.wholeNumber {
display: flex;
align-items: flex-end;
.item-right-num {
font-weight: 400;
font-size: 10px;
color: #333333;
font-style: normal;
padding-bottom: 3px;
}
}
}
&:nth-child(2n) {
margin-right: 0 !important;
}
&:nth-child(3) {
margin-top: 8px !important;
}
&:nth-child(4) {
margin-top: 8px !important;
}
}
}
}
</style>

View File

@ -0,0 +1,109 @@
<script setup lang="ts">
import Panel from "@/components/common/Panel.vue";
import {onMounted, ref} from "vue";
import {getThisWeek} from "@/utils/dateUtils.ts";
import {post} from "@/utils/request.ts";
onMounted(() => {
getRevenueOverview()
})
const payTypeRevenue = ref<any>([
{
name: '医保支付',
totalRevenue: 0,
background: '#F0F4FD'
},
{
name: '微信支付',
totalRevenue: 0,
background: '#ECF8FE'
},
{
name: '支付宝',
totalRevenue: 0,
background: '#FFF5EC'
},
{
name: '现金支付',
totalRevenue: 0,
background: '#FFEEEE'
},
{
name: '其他支付',
totalRevenue: 0,
background: '#E5F9FF'
}
]);
const getRevenueOverview = () => {
const thisWeek = getThisWeek();
post("statistics/getRevenueOverview", {beginTime: thisWeek.start, endTime: thisWeek.end}).then((res: any) => {
if (res.payTypeRevenue.length === 0) return
payTypeRevenue.value = res.payTypeRevenue
})
}
</script>
<template>
<Panel title="支付明细" class="detail-price">
<div class="detail-price-content">
<div class="detail-price-content-item" v-for="(item,index) in payTypeRevenue"
:style="'background:'+item.background">
<img class="detail-price-content-item-image" :src="`/static/images/home/${index+1}.png`" :alt="item.name">
<div class="detail-price-content-item-text">
<div class="detail-price-content-item-text-name">{{ item.name }}</div>
<div class="detail-price-content-item-text-price"><span class="price">{{ item.totalRevenue }}</span>
</div>
</div>
</div>
</div>
</Panel>
</template>
<style scoped lang="scss">
.detail-price {
height: 194px;
&-content {
padding: 0 24px;
display: flex;
&-item {
flex: 1;
height: 110px;
border-radius: 32px;
margin-right: 16px;
display: flex;
align-items: center;
&:last-child {
margin-right: 0;
}
&-image {
width: 40px;
height: 40px;
margin: 0 16px 0 24px;
}
&-text {
font-weight: 500;
font-size: 16px;
color: #333333;
font-style: normal;
margin-right: 24px;
&-price {
font-weight: 400;
font-size: 14px;
.price {
font-weight: bold;
font-size: 32px;
}
}
}
}
}
}
</style>

View File

@ -0,0 +1,63 @@
<script setup lang="ts">
import {defineModel} from "vue"
import Panel from "@/components/common/Panel.vue";
const systemMessage= defineModel()
console.log(systemMessage)
</script>
<template>
<Panel title="系统通知" class="system-notification">
<template #tools>
<el-button type="primary" size="small">查看详情</el-button>
</template>
<div class="system-notification-content">
<el-scrollbar>
<div class="system-notification-item" v-for="(item,index) in systemMessage" :key="index">
<div class="system-notification-item-top">
<span class="system-notification-item-top-title">{{item.title}}</span>
<span>{{item.content}}</span>
</div>
<div class="system-notification-item-bottom">{{item.time}}</div>
</div>
</el-scrollbar>
</div>
</Panel>
</template>
<style scoped lang="scss">
.system-notification-content {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
padding-bottom: 18px;
.system-notification-item {
height: 80px;
width: 100%;
border-bottom: 1px solid #EAEAEC;
display: flex;
flex-direction: column;
justify-content: center;
font-weight: 500;
font-size: 14px;
color: #999999;
font-style: normal;
.system-notification-item-top {
padding: 0 24px;
display: flex;
justify-content: space-between;
&-title {
font-size: 18px;
color: #333333;
}
}
.system-notification-item-bottom {
padding: 0 24px;
}
}
}
</style>

View File

@ -0,0 +1,273 @@
<script setup lang="ts">
import Panel from "@/components/common/Panel.vue";
import {nextTick, ref} from "vue";
import {post} from "@/utils/request.ts";
import ExpireWarnDetail from "@/components/home/index/Dialog/ExpireWarnDetail.vue";
const expireWarnDetailRef = ref()
const openExpireWarnDetail = () => {
nextTick(() => {
expireWarnDetailRef.value.init(expireDateWarningListSrc.value)
})
}
const expireDateWarningListSrc = ref<any>([]);
const expireDateWarningList = ref<any>([]);
const getExpiryDateWarning = () => {
post("statistics/expiryDateWarning").then((res: any) => {
expireDateWarningListSrc.value = res
expireDateWarningList.value = res.slice(0, 3)
})
}
</script>
<template>
<Panel title="效期预警" class="xiaoQi">
<template #tools>
<el-button type="primary" size="small" @click="openExpireWarnDetail">查看详情</el-button>
</template>
<div style="padding: 0 24px 24px">
<div class="box">
<div class="item" style="margin-right: 8px" v-if="expireDateWarningList[0]">
<img class="image" src="/static/images/home/danger.png" alt="">
<div class="item-content">
<el-tooltip
effect="dark"
:content="expireDateWarningList[0].name"
placement="bottom-start"
>
<div class="item-name">{{ expireDateWarningList[0].name }}</div>
</el-tooltip>
<div class="item-name-font">
<span>{{ expireDateWarningList[0].whole_number }}{{ expireDateWarningList[0].packaging_unit }}</span>
<span v-if="expireDateWarningList[0].fragment_number>0">{{
expireDateWarningList[0].fragment_number
}}{{ expireDateWarningList[0].min_packaging_unit }}</span>
</div>
</div>
<div class="item-right">
<div v-if="expireDateWarningList[0].remaining_days<0">已过期<span class="item-right-num">{{
Math.abs(expireDateWarningList[0].remaining_days)
}}</span>
</div>
<div v-else>剩余<span class="item-right-num">{{ Math.abs(expireDateWarningList[0].remaining_days) }}</span>
</div>
</div>
</div>
<div class="item1" style="margin-right: 8px" v-if="expireDateWarningList[1]">
<img class="image" src="/static/images/home/danger.png" alt="">
<div class="item-content">
<el-tooltip
effect="dark"
:content="expireDateWarningList[1].name"
placement="bottom-start"
>
<div class="item-name">{{ expireDateWarningList[1].name }}</div>
</el-tooltip>
<div class="item-name-font">
<span>{{ expireDateWarningList[1].whole_number }}{{ expireDateWarningList[1].packaging_unit }}</span>
<span v-if="expireDateWarningList[1].fragment_number>0">{{
expireDateWarningList[1].fragment_number
}}{{ expireDateWarningList[1].min_packaging_unit }}</span>
</div>
</div>
<div class="item-right">
<div v-if="expireDateWarningList[1].remaining_days<0">已过期<span class="item-right-num">{{
Math.abs(expireDateWarningList[1].remaining_days)
}}</span>
</div>
<div v-else>剩余<span class="item-right-num">{{ Math.abs(expireDateWarningList[1].remaining_days) }}</span>
</div>
</div>
</div>
<div class="item" style="margin-right: 8px" v-if="expireDateWarningList[2]">
<img class="image" src="/static/images/home/danger.png" alt="">
<div class="item-content">
<el-tooltip
effect="dark"
:content="expireDateWarningList[2].name"
placement="bottom-start"
>
<div class="item-name">{{ expireDateWarningList[2].name }}</div>
</el-tooltip>
<div class="item-name-font">
<span>{{ expireDateWarningList[2].whole_number }}{{ expireDateWarningList[2].packaging_unit }}</span>
<span v-if="expireDateWarningList[2].fragment_number>0">{{
expireDateWarningList[2].fragment_number
}}{{ expireDateWarningList[2].min_packaging_unit }}</span>
</div>
</div>
<div class="item-right">
<div v-if="expireDateWarningList[2].remaining_days<0">已过期<span class="item-right-num">{{
Math.abs(expireDateWarningList[2].remaining_days)
}}</span>
</div>
<div v-else>剩余<span class="item-right-num">{{ Math.abs(expireDateWarningList[2].remaining_days) }}</span>
</div>
</div>
</div>
<div class="item1" style="margin-right: 8px" v-if="expireDateWarningList[3]">
<img class="image" src="/static/images/home/danger.png" alt="">
<div class="item-content">
<el-tooltip
effect="dark"
:content="expireDateWarningList[3].name"
placement="bottom-start"
>
<div class="item-name">{{ expireDateWarningList[3].name }}</div>
</el-tooltip>
<div class="item-name-font">
<span>{{ expireDateWarningList[3].whole_number }}{{ expireDateWarningList[3].packaging_unit }}</span>
<span v-if="expireDateWarningList[3].fragment_number>0">{{
expireDateWarningList[3].fragment_number
}}{{ expireDateWarningList[3].min_packaging_unit }}</span>
</div>
</div>
<div class="item-right">
<div v-if="expireDateWarningList[3].remaining_days<0">已过期<span class="item-right-num">{{
Math.abs(expireDateWarningList[3].remaining_days)
}}</span>
</div>
<div v-else>剩余<span class="item-right-num">{{ Math.abs(expireDateWarningList[3].remaining_days) }}</span>
</div>
</div>
</div>
</div>
</div>
</Panel>
<ExpireWarnDetail ref="expireWarnDetailRef"></ExpireWarnDetail>
</template>
<style scoped lang="scss">
.xiaoQi {
height: 100%;
display: flex;
flex-direction: column;
.box {
display: flex;
flex-wrap: wrap;
.item {
float: left;
width: 48%;
height: 58px;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1);
border-radius: 8px;
display: flex;
align-items: center;
.image {
width: 34px;
height: 34px;
margin: 0 8px 0 16px;
}
.item-content {
flex: 1;
.item-name {
font-weight: 400;
font-size: 14px;
color: #333333;
font-style: normal;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.item-right {
width: 56px;
margin-right: 16px;
font-weight: 400;
font-size: 10px;
color: #333333;
font-style: normal;
.item-right-num {
font-weight: bold;
font-size: 28px;
color: #FF282E;
font-style: normal;
}
}
&:nth-child(2n) {
margin-right: 0 !important;
}
&:nth-child(3) {
margin-top: 8px !important;
}
&:nth-child(4) {
margin-top: 8px !important;
}
}
.item1 {
float: right;
height: 58px;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1);
border-radius: 8px;
display: flex;
align-items: center;
.image {
width: 34px;
height: 34px;
margin: 0 8px 0 16px;
}
.item-content {
flex: 1;
.item-name {
font-weight: 400;
font-size: 14px;
color: #333333;
font-style: normal;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.item-right {
width: 56px;
margin-right: 16px;
font-weight: 400;
font-size: 10px;
color: #333333;
font-style: normal;
.item-right-num {
font-weight: bold;
font-size: 28px;
color: #FF282E;
font-style: normal;
}
}
&:nth-child(2n) {
margin-right: 0 !important;
}
&:nth-child(3) {
margin-top: 8px !important;
}
&:nth-child(4) {
margin-top: 8px !important;
}
}
}
}
</style>

View File

@ -1,7 +1,5 @@
<template>
<!-- <CloseBtn @click="exit"></CloseBtn>-->
<div class="header">
<div class="title">新建档案</div>
<el-button type="primary" style="margin-top: 10px" round class="btn" @click="openCreateSearch" v-if="_type!=0" plain>
一键建档
</el-button>
@ -612,11 +610,9 @@ const drugCategoryOptions = [
</script>
<style scoped lang="scss">
@use "@/assets/scss/base.scss";
.header {
.title {
font-size: base.$font-size-large;
font-size: 18px;
font-weight: bold;
}

View File

@ -84,8 +84,8 @@ onMounted(() => {
display: flex;
justify-content: space-between;
align-items: center;
padding: base.$padding-base;
border-radius: base.$border-radius-base;
padding: 8px;
border-radius: 10px;
.name {
display: flex;
@ -105,8 +105,8 @@ onMounted(() => {
width: 100%;
height: 180px;
border: 1px base.$border-color-base solid;
font-size: base.$font-size-small;
border-radius: base.$border-radius-base;
font-size: 14px;
border-radius: 8px;
}

View File

@ -86,7 +86,6 @@ const formatDate = (isoStr:any) => {
}
</script>
<style scoped lang="scss">
@use "@/assets/scss/base.scss";
.container {
position: relative;
width: 100%;
@ -109,8 +108,6 @@ const formatDate = (isoStr:any) => {
padding-left: 10px;
align-items: center;
color: #bac2ca;
background-color: base.$background-color-b1;
border-radius: base.$border-radius-base;
.name{
font-size: 16px;
margin-right: 10px;
@ -133,7 +130,6 @@ const formatDate = (isoStr:any) => {
height: 60px;
display: flex;
align-items: center;
background: base.$background-color-panel;
}
}

View File

@ -2,316 +2,53 @@
<div class="container-wrapper">
<div class="left">
<div class="yuJin">
<Panel title="库存预警" class="kuCun">
<template #tools>
<el-button type="primary" size="small" @click="openInventoryWarnDetail">查看详情</el-button>
</template>
<div style="padding: 0 24px 24px">
<div class="box">
<!-- <div class="item" style="margin-right: 8px">-->
<!-- <img class="image" src="/static/images/home/1-danger.png" alt=""/>-->
<!-- <div class="item-content">-->
<!-- <el-tooltip-->
<!-- effect="dark"-->
<!-- :content="inventoryWarnList[0].name"-->
<!-- placement="bottom-start"-->
<!-- >-->
<!-- <div class="item-name">{{ inventoryWarnList[0].name }}</div>-->
<!-- </el-tooltip>-->
<!-- <div class="item-name-font">剩余库存值</div>-->
<!-- </div>-->
<!-- <div class="item-right">-->
<!-- <div class="wholeNumber">{{ inventoryWarnList[0].inventoryWholeNumber }}-->
<!-- <div class="item-right-num">{{ inventoryWarnList[0].packagingUnit }}</div>-->
<!-- </div>-->
<!-- <div class="wholeNumber" v-if="inventoryWarnList[0].inventoryFragmentNumber>0">{{ inventoryWarnList[0].inventoryFragmentNumber }}-->
<!-- <div class="item-right-num" v-if="inventoryWarnList[0].inventoryFragmentNumber>0">{{ inventoryWarnList[0].minPackagingUnit }}</div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<div class="kuCun">
<InventoryAlert></InventoryAlert>
</div>
<div class="xiaoQi">
<ValidityWarning></ValidityWarning>
</div>
</div>
</Panel>
<Panel title="效期预警" class="xiaoQi">
<template #tools>
<el-button type="primary" size="small" @click="openExpireWarnDetail">查看详情</el-button>
</template>
<div style="padding: 0 24px 24px">
<div class="box">
<div class="item" style="margin-right: 8px" v-for="item in expireDateWarningList">
<img class="image" src="/static/images/home/danger.png" alt="">
<div class="item-content">
<el-tooltip
effect="dark"
:content="item.name"
placement="bottom-start"
>
<div class="item-name">{{ item.name }}</div>
</el-tooltip>
<div class="item-name-font">
<span>{{ item.whole_number }}{{ item.packaging_unit }}</span>
<span v-if="item.fragment_number>0">{{ item.fragment_number }}{{ item.min_packaging_unit }}</span>
<div class="business">
<BusinessOverview></BusinessOverview>
</div>
</div>
<div class="item-right">
<div v-if="item.remaining_days<0">已过期<span class="item-right-num">{{
Math.abs(item.remaining_days)
}}</span>
</div>
<div v-else>剩余<span class="item-right-num">{{ Math.abs(item.remaining_days) }}</span></div>
</div>
</div>
<div v-show="expireDateWarningList.length <3" class="item"
style="margin-top: 8px;margin-right: 8px;box-shadow:none"></div>
<div v-show="expireDateWarningList.length <4" class="item" style="margin-top: 8px;box-shadow:none"></div>
</div>
</div>
</Panel>
</div>
<div class="jinYing">
<Panel title="经营概况">
<div class="tu" ref="echart" style="height: 100%;width: 100%"></div>
</Panel>
</div>
<Panel title="支付明细" class="detail-price">
<div class="detail-price-content">
<div class="detail-price-content-item" v-for="(item,index) in payTypeRevenue"
:style="'background:'+item.background">
<img class="detail-price-content-item-image" :src="`/static/images/home/${index+1}.png`" :alt="item.name">
<div class="detail-price-content-item-text">
<div class="detail-price-content-item-text-name">{{ item.name }}</div>
<div class="detail-price-content-item-text-price"><span class="price">{{ item.totalRevenue }}</span>
</div>
</div>
</div>
</div>
</Panel>
<PanmentDetail></PanmentDetail>
</div>
<div class="right">
<Card></Card>
<Panel title="客服支持" class="service">
<div class="service-content">
<img class="image" src="/static/images/home/qr-code.png" alt="">
<div class="service-text">
<div style="margin-bottom: 20px">服务时间09:00-18:00</div>
<div>服务热线400-999888</div>
<CustomerService v-model="proxyMessage"></CustomerService>
<SystemMessage v-model="systemMessage"></SystemMessage>
<Banner></Banner>
</div>
</div>
</Panel>
<Panel title="系统通知" class="system-notification">
<template #tools>
<el-button type="primary" size="small">查看详情</el-button>
</template>
<div class="system-notification-content">
<el-scrollbar>
<div class="system-notification-item">
<div class="system-notification-item-top">
<span class="system-notification-item-top-title">系统版本更新</span>
<span>2024-04-01</span>
</div>
<div class="system-notification-item-bottom">优化库存管理模块新增批次</div>
</div>
<div class="system-notification-item">
<div class="system-notification-item-top">
<span class="system-notification-item-top-title">系统版本更新</span>
<span>2024-04-01</span>
</div>
<div class="system-notification-item-bottom">优化库存管理模块新增批次</div>
</div>
</el-scrollbar>
</div>
</Panel>
<div class="banner">
<el-carousel style="height: 100%">
<el-carousel-item v-for="(item,index) in imageList" :key="index">
<img class="image" :src="item.image" alt="">
</el-carousel-item>
</el-carousel>
</div>
</div>
</div>
<ExpireWarnDetail ref="expireWarnDetailRef"></ExpireWarnDetail>
<InventoryWarnDetail ref="inventoryWarnDetailRef"></InventoryWarnDetail>
</template>
<script setup lang="ts">
import {ref, onMounted, onUnmounted, nextTick} from "vue"
import * as echarts from 'echarts';
import {post} from "@/utils/request.ts";
import {getThisWeek, getDaysBetweenDates} from "@/utils/dateUtils.ts";
import InventoryWarnDetail from "@/components/home/index/Dialog/InventoryWarnDetail.vue";
import {ref, onMounted, nextTick} from "vue"
import ExpireWarnDetail from "@/components/home/index/Dialog/ExpireWarnDetail.vue";
import Panel from "@/components/common/Panel.vue";
import Card from "@/components/home/index/Card.vue";
import CustomerService from "@/components/home/index/CustomerService.vue";
import SystemMessage from "@/components/home/index/SystemMessage.vue";
import Banner from "@/components/home/index/Banner.vue";
import PanmentDetail from "@/components/home/index/PanmentDetail.vue";
import BusinessOverview from "@/components/home/index/BusinessOverview.vue";
import InventoryAlert from "@/components/home/index/InventoryAlert.vue";
import ValidityWarning from "@/components/home/index/ValidityWarning.vue";
const echart = ref<HTMLElement | null>(null)
let myChart: echarts.ECharts | null = null;
const dateList = ref([
'2024-04-01',
'2024-03-30',
'2024-03-26',
'2024-03-22',
'2024-03-18',
'2024-03-14',
'2024-03-10',
'2024-03-06',
'2024-03-02',
])
const vipData = ref([120, 132, 101, 134, 90, 230, 210])
const commonData = ref([220, 182, 191, 234, 290, 330, 310])
const initEcharts = (dateList: any[], vipData: any, commonData: any) => {
if (myChart) {
myChart.dispose();
}
myChart = echarts.init(echart.value);
myChart.setOption(
{
title: {
text: ''
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['会员', '普通',]
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: true,
data: dateList
},
yAxis: {
type: 'value'
},
series: [
{
name: '会员',
type: 'line',
stack: 'Total',
data: vipData
},
{
name: '普通',
type: 'line',
stack: 'Total',
data: commonData
}
]
}
);
}
onMounted(() => {
initEcharts(dateList.value, vipData.value, commonData.value)
getInventoryWarning()
getExpiryDateWarning()
getRevenueOverview()
getPersonPayOverview()
window.addEventListener('resize', handleResize);
getData()
})
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
});
const handleResize = () => {
if (myChart) {
myChart.resize();
}
};
const systemMessage = ref("")
const proxyMessage = ref("")
let appConfig: any = null;
const imageList = [
{
image: '/static/images/home/banner.png'
},
{
image: '/static/images/home/banner1.png'
},
{
image: '/static/images/home/banner2.png'
},
{
image: '/static/images/home/banner3.png'
async function getData() {
const response = await fetch('/info/data.json?v=' + Date.now());
appConfig = await response.json();
systemMessage.value = appConfig.systemMessage
proxyMessage.value = appConfig.proxy
}
]
const inventoryWarnListSrc = ref<any>([]);
const inventoryWarnList = ref<any>([]);
const expireDateWarningListSrc = ref<any>([]);
const expireDateWarningList = ref<any>([]);
const payTypeRevenue = ref<any>([
{
name: '医保支付',
totalRevenue: 0,
background: '#F0F4FD'
},
{
name: '微信支付',
totalRevenue: 0,
background: '#ECF8FE'
},
{
name: '支付宝',
totalRevenue: 0,
background: '#FFF5EC'
},
{
name: '现金支付',
totalRevenue: 0,
background: '#FFEEEE'
},
{
name: '其他支付',
totalRevenue: 0,
background: '#E5F9FF'
}
]);
const getInventoryWarning = () => {
post("statistics/numberEarlyWarning").then((res: any) => {
inventoryWarnListSrc.value = res
expireDateWarningList.value = res.slice(0, 3)
})
}
const getExpiryDateWarning = () => {
post("statistics/expiryDateWarning").then((res: any) => {
expireDateWarningListSrc.value = res
expireDateWarningList.value = res.slice(0, 3)
console.log(expireDateWarningList)
})
}
const getRevenueOverview = () => {
const thisWeek = getThisWeek();
post("statistics/getRevenueOverview", {beginTime: thisWeek.start, endTime: thisWeek.end}).then((res: any) => {
if (res.payTypeRevenue.length === 0) return
payTypeRevenue.value = res.payTypeRevenue
})
}
const getPersonPayOverview = () => {
const thisWeek = getThisWeek();
post("statistics/getPersonPayOverview", {beginTime: thisWeek.start, endTime: thisWeek.end}).then((res: any) => {
dateList.value = res.dateList
vipData.value = res.vipPrice
commonData.value = res.commonPrice
// initEcharts(dateList.value, vipData.value, commonData.value)
})
}
const expireWarnDetailRef = ref()
const openExpireWarnDetail = () => {
nextTick(() => {
expireWarnDetailRef.value.init(expireDateWarningListSrc.value)
})
}
const inventoryWarnDetailRef = ref()
const openInventoryWarnDetail = () => {
nextTick(() => {
inventoryWarnDetailRef.value.init(inventoryWarnListSrc.value)
})
}
</script>
<style scoped lang="scss">
@use "@/assets/scss/base";
@ -330,209 +67,18 @@ const openInventoryWarnDetail = () => {
.yuJin {
height: 208px;
display: flex;
.kuCun{
height: 100%;
flex: 1;
display: flex;
flex-direction: column;
margin-right: 24px;
.box {
display: flex;
flex-wrap: wrap;
.item {
height: 58px;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: space-between;
flex: 1 1 calc(50% - 8px); //2 item item 33.33%
.image {
width: 34px;
height: 34px;
margin: 0 8px 0 16px;
}
.item-content {
flex: 1;
.item-name {
font-weight: 400;
font-size: 14px;
color: #333333;
font-style: normal;
}
.item-name-font {
font-weight: 400;
font-size: 12px;
color: #999999;
font-style: normal;
}
}
.item-right {
width: 70px;
display: flex;
margin-right: 16px;
font-weight: bold;
font-style: normal;
font-size: 28px;
color: #FF282E;
align-items: flex-end;
.wholeNumber {
display: flex;
align-items: flex-end;
.item-right-num {
font-weight: 400;
font-size: 10px;
color: #333333;
font-style: normal;
padding-bottom: 3px;
}
}
}
&:nth-child(2n) {
margin-right: 0 !important;
}
&:nth-child(3) {
margin-top: 8px !important;
}
&:nth-child(4) {
margin-top: 8px !important;
}
}
}
}
.xiaoQi{
flex: 1;
height: 100%;
display: flex;
flex-direction: column;
.box {
display: flex;
flex-wrap: wrap;
.item {
height: 58px;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1);
border-radius: 8px;
display: flex;
align-items: center;
.image {
width: 34px;
height: 34px;
margin: 0 8px 0 16px;
}
.item-content {
flex: 1;
.item-name {
font-weight: 400;
font-size: 14px;
color: #333333;
font-style: normal;
}
}
.item-right {
width: 56px;
margin-right: 16px;
font-weight: 400;
font-size: 10px;
color: #333333;
font-style: normal;
.item-right-num {
font-weight: bold;
font-size: 28px;
color: #FF282E;
font-style: normal;
}
}
&:nth-child(2n) {
margin-right: 0 !important;
}
&:nth-child(3) {
margin-top: 8px !important;
}
&:nth-child(4) {
margin-top: 8px !important;
}
}
}
}
}
.jinYing {
.business {
flex: 1;
margin: 24px 0;
background: #fff;
border-radius: 8px 8px 8px 8px;
}
.detail-price {
height: 194px;
&-content {
padding: 0 24px;
display: flex;
&-item {
flex: 1;
height: 110px;
border-radius: 32px;
margin-right: 16px;
display: flex;
align-items: center;
&:last-child {
margin-right: 0;
}
&-image {
width: 40px;
height: 40px;
margin: 0 16px 0 24px;
}
&-text {
font-weight: 500;
font-size: 16px;
color: #333333;
font-style: normal;
margin-right: 24px;
&-price {
font-weight: 400;
font-size: 14px;
.price {
font-weight: bold;
font-size: 32px;
}
}
}
}
}
}
}
@ -541,118 +87,17 @@ const openInventoryWarnDetail = () => {
display: flex;
flex-direction: column;
.info {
height: 208px;
.info-content {
display: flex;
.image {
width: 88px;
height: 88px;
margin: 0 24px;
}
.app_info-content-text {
font-weight: 500;
font-size: 16px;
color: #333333;
font-style: normal;
.app_info-title {
max-width: 220px;
font-weight: bold;
font-size: 20px;
margin-bottom: 20px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
.service {
height: 170px;
margin: 24px 0;
padding-bottom: 24px;
.service-content {
display: flex;
.image {
width: 88px;
height: 88px;
margin: 0 24px;
}
.service-text {
font-weight: 500;
font-size: 16px;
color: #333333;
font-style: normal;
display: flex;
flex-direction: column;
justify-content: center;
}
}
}
.system-notification {
flex: 1;
.system-notification-content {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
padding-bottom: 18px;
.system-notification-item {
height: 80px;
width: 100%;
border-bottom: 1px solid #EAEAEC;
display: flex;
flex-direction: column;
justify-content: center;
font-weight: 500;
font-size: 14px;
color: #999999;
font-style: normal;
.system-notification-item-top {
padding: 0 24px;
display: flex;
justify-content: space-between;
&-title {
font-size: 18px;
color: #333333;
}
}
.system-notification-item-bottom {
padding: 0 24px;
}
}
}
}
.banner {
height: 154px;
background: #FFFFFF;
border-radius: 8px 8px 8px 8px;
margin-top: 24px;
.image {
width: 100%;
height: 100%;
border-radius: 8px 8px 8px 8px;
}
}
}
}
@media (max-width: 1920px) {
.item-name {
max-width: 70px;

View File

@ -167,11 +167,10 @@
</div>
</div>
</div>
<Mask :is-show="is_add" :top="50" :height="900">
<Mask :is-show="is_add" :top="50" :height="900" @close="is_add = false" title="新建档案">
<Edit ref="editRef" @close="is_add = false;init()"/>
</Mask>
<Mask :is-show="open" :top="50" :height="600">
<Mask :is-show="open" :top="50" :height="600" @close="open=false" title="列表信息">
<el-tabs v-model="activeName" @tab-change="changeTab">
<el-tab-pane label="商品信息" name="first">
<Edit ref="editRef" @close="open = false;init()"/>
@ -385,8 +384,6 @@ const changeTab = (name: string) => {
const activeName = ref('first')
</script>
<style scoped lang="scss">
@use "@/assets/scss/base.scss";
.v-enter-active,
.v-leave-active {
transition: opacity 0.5s ease;

View File

@ -83,6 +83,7 @@ function set_tab() {
post("social/directory/column_list", {type: current_tab.value})
.then((res: any) => {
column_list.value = res;
console.log(column_list)
get_data_list();
})
}
@ -100,17 +101,15 @@ function get_data_list() {
isDownLoading.value = false;
total_page.value = res.total_page;
tableData.value = res.list
tableData.value.forEach((item: any) => {
if (item.enddate == null) {
item.enddate = "长期有效"
}
if (item.json.rx_flag) {
item.json.rx_flag = item.json.rx_flag == 1 ? "是" : "否"
}
// tableData.value.forEach((item: any) => {
// if (item.enddate == null) {
// item.enddate = ""
// }
// if (item.json.rx_flag) {
// item.json.rx_flag = item.json.rx_flag == 1 ? "" : ""
// }
// })
})
})
console.log("tabledaTA", tableData.value)
}
let change_page = (val: number) => {