feat:充值/扣款发票管理(按月)

This commit is contained in:
dzc committed 2026-01-15 16:38:23 +08:00
1 parent f2bd781efc
commit 2def987861
5 files changed
+56 -23

No files matched your search

+22 -14
View File
@@ -1,10 +1,8 @@
<template>
<div class="layout-padding">
<div class="layout-padding-view">
<div
ref="containerRef"
class="relative h-full w-full overflow-y-scroll scrollbar-hidden bg-gradient-to-br from-[#232e55] to-[#040a1b] py-2"
>
<div ref="containerRef"
class="relative h-full w-full overflow-y-scroll scrollbar-hidden bg-gradient-to-br from-[#232e55] to-[#040a1b] py-2">
<!-- 背景圆点 -->
<div class="pointer-events-none absolute inset-0 pattern-dots opacity-[0.08]"></div>
@@ -24,16 +22,17 @@
<div class="h-8 relative mx-4 flex items-center justify-between">
<div class="flex items-center">
<h1 class="text-4xl text-[#b0bfff] font-bold tracking-wider">今日午餐菜品</h1>
<div class="text-xl text-blue-400 drop-shadow-lg ml-5">{{ currentDate }}&nbsp;&nbsp;&nbsp;{{ currentTime }}</div>
<div class="text-xl text-blue-400 drop-shadow-lg ml-5">{{ currentDate }}&nbsp;&nbsp;&nbsp;{{
currentTime }}</div>
</div>
<!-- 全屏按钮 -->
<el-tooltip :content="isFullscreen ? '退出全屏' : '全屏'" placement="left" effect="dark">
<button
@click="toggleFullScreen"
class="flex h-8 w-8 items-center justify-center rounded-xl bg-[#F7D6C3]/20 transition-all hover:scale-110 hover:bg-[#F7D6C3]/40"
>
<el-icon class="icon h-10 w-10 font-bold bg-contain bg-center bg-no-repeat"><FullScreen /></el-icon>
<button @click="toggleFullScreen"
class="flex h-8 w-8 items-center justify-center rounded-xl bg-[#F7D6C3]/20 transition-all hover:scale-110 hover:bg-[#F7D6C3]/40">
<el-icon class="icon h-10 w-10 font-bold bg-contain bg-center bg-no-repeat">
<FullScreen />
</el-icon>
</button>
</el-tooltip>
</div>
@@ -42,17 +41,21 @@
<div class="w-full flex flex-wrap items-center" v-for="(hourType, index) in foodData" :key="index">
<div v-for="dish in hourType" :key="dish.id" class="p-2" :style="cardStyle">
<div class="relative overflow-hidden rounded-tl rounded-tr" :style="foodCardStyle">
<img :src="imageBaseUrl + dish.picUrl" :alt="dish.name" class="h-full w-full object-cover" />
<img :src="imageBaseUrl + dish.picUrl" :alt="dish.name"
class="h-full w-full object-cover" />
<div class="ribbon">午餐</div>
<div class="absolute left-1 top-1">
<star-medal :text="canteenCategoryOption?.find((v: any) => v.id == dish.categoryId)?.name" />
<star-medal
:text="canteenCategoryOption?.find((v: any) => v.id == dish.categoryId)?.name" />
</div>
</div>
<div class="w-full flex items-center justify-between bg-[#AEBBF9]/40 px-2 py-2 backdrop-blur-sm rounded-bl rounded-br">
<div
class="w-full flex items-center justify-between bg-[#AEBBF9]/40 px-2 py-2 backdrop-blur-sm rounded-bl rounded-br">
<h3 class="text-2xl font-bold text-[#7cacff] drop-shadow-lg line-clamp-1 whitespace-nowrap">
{{ dish.name }}
</h3>
<p class="text-3xl font-bold text-[#a9c7ff] drop-shadow-lg whitespace-nowrap">¥{{ displayPrice(dish.price) }}</p>
<p class="text-3xl font-bold text-[#a9c7ff] drop-shadow-lg whitespace-nowrap">¥{{
displayPrice(dish.price) }}</p>
</div>
</div>
</div>
@@ -218,23 +221,28 @@ const getCanteenDishesCategory = async () => {
background-image: radial-gradient(#eff4ee 1px, transparent 10px);
background-size: 10px 10px;
}
.ink-cloud {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath fill='%23F7D6C3' d='M50,0C36.7,0,25,11.7,25,25c0,13.3,11.7,25,25,25s25-11.7,25-25C75,11.7,63.3,0,50,0z M50,40c-8.3,0-15-6.7-15-15s6.7-15,15-15s15,6.7,15,15S58.3,40,50,40z'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 50 50' to='360 50 50' dur='20s' repeatCount='indefinite'/%3E%3C/path%3E%3C/svg%3E");
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
.scrollbar-hidden::-webkit-scrollbar {
display: none;
}
.scrollbar-hidden {
scrollbar-width: none;
-ms-overflow-style: none;
}
::selection {
background: #1879ff;
color: #fff;
}
.ribbon {
width: 80px;
height: 20px;
@@ -152,6 +152,7 @@ const tableExpandChange = async (e: any) => {
try {
const { data } = await hardTotalApi.productTotalByDept({
hourType: e.hourType,
createTimeType: '0',
createTimeStr: parseTime(e.createTime, '{y}-{m}-{d}'),
})
if (data && data.length) {
@@ -152,7 +152,8 @@ const tableExpandChange = async (e: any) => {
try {
const { data } = await hardTotalApi.productTotalByDept({
hourType: e.hourType,
createTimeStr: parseTime(e.createTime, '{y}-{m}-{d}'),
createTimeType: '1',
createTimeStr: parseTime(e.createTime, '{y}-{m}'),
})
if (data && data.length) {
tableChildrenMap.value.set(e.uniqueCode, data)
+28 -8
View File
@@ -14,10 +14,16 @@
<select-mch v-model="state.queryForm.merchantId"
:apiParams="{ parentIsNull: false, types: '1' }" />
</el-form-item>
<el-form-item style="width: 450px" label="创建时间" prop="createTimeList">
<el-form-item v-if="activeTab === 'DAY'" style="width: 450px" label="创建时间(天)"
prop="createTimeList">
<el-date-picker v-model="state.queryForm.createTimeList"
value-format="YYYY-MM-DD HH:mm:ss" type="daterange" />
</el-form-item>
<el-form-item v-if="activeTab === 'MONTH'" style="width: 450px" label="创建时间(年)"
prop="createTimeYearStr">
<el-date-picker value-format="YYYY" v-model="state.queryForm.createTimeYearStr"
type="year" />
</el-form-item>
<el-form-item>
<el-button icon="Search" type="primary" @click="search">
{{ $t("common.queryBtn") }}
@@ -28,8 +34,8 @@
</el-form>
<el-row class="flex">
<el-tabs class="flex-1" v-model="activeTab">
<el-tab-pane v-for="(v) in tabPane" :key="v.name" :label="v.label" :name="v.name">
</el-tab-pane>
<el-tab-pane v-for="(v) in tabPane" :key="v.name" :label="v.label" :name="v.name"
@tab-click="tabClick" />
</el-tabs>
<div class="mb8">
<right-toolbar :search="false" v-model:showSearch="showSearch"
@@ -48,6 +54,7 @@
<script setup lang="ts" name="hard-sb">
import { ElMessage } from "element-plus"
import dayjs from "dayjs"
import other from "/@/utils/other"
import { formatDate } from '/@/utils/formatTime';
@@ -79,12 +86,14 @@ const tabPane = ref([
])
const activeTab = ref("DAY")
const defaultQueryForm = {
hourType: "",
merchantId: "",
createTimeList: [],
createTimeYearStr: dayjs().format("YYYY"),
}
const state = reactive<any>({
queryForm: {
hourType: "",
merchantId: "",
createTimeList: [],
}
queryForm: { ...defaultQueryForm }
})
watch(() => [activeTab.value, productTotalTableByDayRef.value, productTotalTableByMonthRef.value], () => {
@@ -126,7 +135,17 @@ const handleGetSelectNode = (curClickedNode: any, checkedTreeNodes: any, isDeepT
search()
}
const tabClick = () => {
cancel()
}
const search = () => {
if (activeTab.value === "DAY") {
state.queryForm.createTimeYearStr = ""
}
if (activeTab.value === "MONTH") {
state.queryForm.createTimeList = []
}
switch (activeTab.value) {
case "DAY":
productTotalTableByDayRef.value.doSearch(state.queryForm)
@@ -138,6 +157,7 @@ const search = () => {
}
const cancel = () => {
state.queryForm = { ...defaultQueryForm }
switch (activeTab.value) {
case "DAY":
productTotalTableByDayRef.value.doCancel(state.queryForm)
@@ -13,6 +13,9 @@
<el-form-item style="width: 350px" label="发票状态" prop="userIds">
<dict-select v-model="state.queryForm.status" dict-code="recharge_invoice_status" />
</el-form-item>
<el-form-item style="width: 350px" label="发票号" prop="code">
<el-input v-model="state.queryForm.code" />
</el-form-item>
<el-form-item style="width: 350px" label="备注" prop="remark">
<el-input v-model="state.queryForm.remark" />
</el-form-item>