Merge remote-tracking branch 'origin/master'

This commit is contained in:
zjf committed 2025-07-01 18:50:33 +08:00
commit 781a825b9c
7 files changed
+273 -311

No files matched your search

@@ -1,9 +1,5 @@
import request from "/@/utils/request"
/**
* 根据申请id获取发票详情
* @param id 申请id
*/
export function invoiceBack(query: any) {
return request({
url: "/wallet/walletRechargeInvoice/back",
+95 -71
View File
@@ -1,25 +1,43 @@
<template>
<el-select style="width: 100%" v-model="state.selectId" :placeholder="props.placeholder"
:clearable="props.clearable" remote-show-suffix filterable remote :disabled="props.disabled"
:remote-method="remoteSearch" :loading="state.loading" @visible-change="(e: boolean) => e && getOptions()"
@change="change">
<el-option v-for="v in state.options" :key="v.id"
:label="`向${v.payeeDept}汇款${displayPrice(v.totalPrice)}用于充值-创建于${v.createTime}`" :value="v.id">
<div class="flex items-center">
向
<span class="color-danger">{{ v.payeeDept }}</span>
汇款
<span class="color-danger">{{ displayPrice(v.totalPrice) }}</span>
用于充值
<span>-创建于{{ v.createTime }}</span>
</div>
</el-option>
</el-select>
<el-select
style="width: 100%"
v-model="state.selectId"
:placeholder="props.placeholder"
:clearable="props.clearable"
remote-show-suffix
filterable
remote
:disabled="props.disabled"
:remote-method="remoteSearch"
:loading="state.loading"
@visible-change="(e: boolean) => e && getOptions()"
@change="change"
>
<el-option
v-for="v in state.options"
:key="v.id"
:label="`${v.code}-${v.deptOrUser}向${v.payeeDept}汇款${displayPrice(v.totalPrice)}用于充值-创建于${v.createTime}`"
:value="v.id"
>
<div class="flex items-center">
<span class="color-danger">{{ v.code }}</span>
-
<span class="color-danger">{{ v.deptOrUser }}</span>
向
<span class="color-danger">{{ v.payeeDept }}</span>
汇款
<span class="color-danger">{{ displayPrice(v.totalPrice) }}</span>
用于充值
<span>-创建于{{ v.createTime }}</span>
</div>
</el-option>
</el-select>
</template>
<script setup lang="ts" name="select-wallet-invoice">
import { reactive } from "vue"
import { useDict } from "/@/hooks/dict"
import { useUserInfo } from "/@/stores/userInfo"
import { displayPrice } from "/@/utils/formatMoney"
import * as invoiceManager from "/@/api/wallet/wallet-recharge-invoice"
@@ -29,84 +47,90 @@ const emit = defineEmits(["change"])
const selectId = defineModel()
const props = withDefaults(
defineProps<{
placeholder?: string
disabled?: boolean
clearable?: boolean
autoFirst?: boolean
apiParams?: any
}>(),
{
placeholder: "请选择",
disabled: false,
clearable: true,
autoFirst: false,
apiParams: {
status: "1"
},
},
defineProps<{
placeholder?: string
disabled?: boolean
clearable?: boolean
autoFirst?: boolean
apiParams?: any
}>(),
{
placeholder: "请选择",
disabled: false,
clearable: true,
autoFirst: false,
apiParams: {
status: "1",
},
},
)
const queryForm = reactive<any>({
name: "",
current: 1,
size: 10,
name: "",
current: 1,
size: 10,
})
const state = reactive<any>({
loading: true,
selectId: selectId,
options: [],
hardType: [],
loading: true,
selectId: selectId,
options: [],
hardType: [],
})
const currentUserId = computed(() => {
return useUserInfo().userInfos.user.userId
})
watch(
selectId,
(newVal, oldValue) => {
if (newVal == oldValue) return
state.selectId = newVal
getOptions()
},
{ immediate: true },
selectId,
(newVal, oldValue) => {
if (newVal == oldValue) return
state.selectId = newVal
getOptions()
},
{ immediate: true },
)
async function getOptions() {
try {
state.loading = true
const _pa = {
...queryForm,
...props.apiParams,
}
const { data } = await invoiceManager.invoiceSelect(_pa)
state.options = data.records ?? []
if (props.autoFirst && state.options.length != 0) {
state.selectId = state.options[0].id
emit("change", state.selectId)
}
const { hard_type } = useDict("hard_type")
state.hardType = hard_type
} finally {
setTimeout(() => (state.loading = false), 500)
}
try {
state.loading = true
const _pa = {
...queryForm,
...props.apiParams,
userIds: [currentUserId.value],
}
const { data } = await invoiceManager.invoiceSelect(_pa)
state.options = data.records ?? []
if (props.autoFirst && state.options.length != 0) {
state.selectId = state.options[0].id
emit("change", state.selectId)
}
const { hard_type } = useDict("hard_type")
state.hardType = hard_type
} finally {
setTimeout(() => (state.loading = false), 500)
}
}
function remoteSearch(params: string) {
if (params != queryForm.name) {
queryForm.name = params
getOptions()
}
if (params != queryForm.name) {
queryForm.name = params
getOptions()
}
}
function clear() {
state.selectId = null
getOptions()
state.selectId = null
getOptions()
}
function change() {
emit("change", selectId)
emit("change", selectId)
}
onMounted(() => {
props.autoFirst && getOptions()
props.autoFirst && getOptions()
})
</script>
+28 -72
View File
@@ -1,16 +1,9 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<DraggableDepTree
ref="draggableDepTreeRef"
placeholder="请输入部门名称"
:show-expand="true"
@getSelectNode="handleGetSelectNode"
switch-inactive-text="包含"
switch-active-text="不包含"
:defaultTreeWidth="20"
:nodeClickable="false"
>
<DraggableDepTree ref="draggableDepTreeRef" placeholder="请输入部门名称" :show-expand="true"
@getSelectNode="handleGetSelectNode" switch-inactive-text="包含" switch-active-text="不包含"
:defaultTreeWidth="20" :nodeClickable="false">
<template #default>
<el-form ref="queryRef" :inline="true" :model="state.queryForm" @keyup.enter="getDataList">
<el-row>
@@ -21,47 +14,30 @@
<el-input v-model="state.queryForm.cardNumber" placeholder="饭卡卡号" clearable />
</el-form-item>
<el-form-item style="width: 200px" label="饭卡类型" prop="walletTypeId">
<select-wallet-type v-model="state.queryForm.walletTypeId" placeholder="饭卡类型" clearable />
<select-wallet-type v-model="state.queryForm.walletTypeId" placeholder="饭卡类型"
clearable />
</el-form-item>
<el-form-item>
<el-button icon="Search" type="primary" @click="getDataList">{{ $t("common.queryBtn") }}</el-button>
<el-button icon="Search" type="primary" @click="getDataList">{{ $t("common.queryBtn")
}}</el-button>
<el-button icon="Refresh" @click="resetQuery">{{ $t("common.resetBtn") }}</el-button>
</el-form-item>
</el-row>
</el-form>
<el-row>
<div class="mb8" style="width: 100%">
<el-button
plain
:disabled="multiple"
icon="Delete"
type="primary"
v-auth="'wallet_walletManage_del'"
@click="handleDelete(selectObjs)"
>
<el-button plain :disabled="multiple" icon="Delete" type="primary"
v-auth="'wallet_walletManage_del'" @click="handleDelete(selectObjs)">
删除
</el-button>
<right-toolbar
v-model:showSearch="showSearch"
:export="'wallet_walletManage_export'"
@exportExcel="exportExcel"
class="ml10 mr20"
style="float: right"
@queryTable="getDataList"
></right-toolbar>
<right-toolbar v-model:showSearch="showSearch" :export="'wallet_walletManage_export'"
@exportExcel="exportExcel" class="ml10 mr20" style="float: right"
@queryTable="getDataList"></right-toolbar>
</div>
</el-row>
<el-table
:data="state.dataList"
v-loading="state.loading"
border
:summary-method="getSummaries"
show-summary
:cell-style="tableStyle.cellStyle"
:header-cell-style="tableStyle.headerCellStyle"
@selection-change="selectionChangHandle"
@sort-change="sortChangeHandle"
>
<el-table :data="state.dataList" v-loading="state.loading" border :summary-method="getSummaries"
show-summary :cell-style="tableStyle.cellStyle" :header-cell-style="tableStyle.headerCellStyle"
@selection-change="selectionChangHandle" @sort-change="sortChangeHandle">
<el-table-column type="selection" width="40" align="center" />
<el-table-column type="index" label="#" width="80" />
<el-table-column prop="username" width="100" label="用户" />
@@ -105,49 +81,29 @@
</el-table-column>
<el-table-column v-if="false" prop="activeBindStatus" width="120" label="饭卡绑定状态" />
<el-table-column prop="createTime" width="200" label="创建时间" />
<el-table-column
label="操作"
fixed="right"
width="250"
v-auths="[
'wallet_walletManage_edit',
'wallet_walletTransaction_update_balance',
'wallet_walletRuleTransaction_transfer_accounts',
]"
>
<el-table-column label="操作" fixed="right" width="250" v-auths="[
'wallet_walletManage_edit',
'wallet_walletTransaction_update_balance',
'wallet_walletRuleTransaction_transfer_accounts',
]">
<template #default="{ row }">
<div class="flex items-start">
<el-button
icon="InfoFilled"
text
type="primary"
v-auth="'wallet_walletManage_edit'"
@click="formDialogRef.openDialog(row.id)"
>详情</el-button
>
<el-button
icon="Money"
text
type="primary"
<el-button icon="InfoFilled" text type="primary" v-auth="'wallet_walletManage_edit'"
@click="formDialogRef.openDialog(row.id)">详情</el-button>
<el-button icon="Money" text type="primary"
v-auth="'wallet_walletTransaction_update_balance'"
@click="changeBalanceRef.openDialog(row.userId, row.id)"
>充值/扣款</el-button
>
<el-button
v-if="row.isRule == 1"
icon="SwitchFilled"
text
type="primary"
@click="changeBalanceRef.openDialog(row.userId, row.id)">充值/扣款</el-button>
<el-button v-if="row.isRule == 1" icon="SwitchFilled" text type="primary"
v-auth="'wallet_walletRuleTransaction_transfer'"
@click="doTransferAccounts(row)"
>
@click="doTransferAccounts(row)">
转账
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle"
v-bind="state.pagination" />
</template>
</DraggableDepTree>
</div>
@@ -14,7 +14,7 @@
<el-form-item label="充值类型" prop="bizType">
<!-- :hide-ids="[(roleCodes.includes('RETURN_CANTEEN') || auths(['wallet_walletRechargeApply_refund'])) ? '' : '3', auths(['wallet_walletRechargeApply_select_jz']) ? '' : '2', '1']" -->
<dict-select v-model="form.bizType" :disabled="form.invoiceId" dict-code="wallet_biz_recharge"
:hide-ids="[(roleCodes.includes('RETURN_CANTEEN') || auths(['wallet_walletRechargeApply_refund'])) ? '' : '3', auths(['wallet_walletRechargeApply_select_jz']) ? '' : '2']"
:hide-ids="[(roleCodes.includes('RETURN_CANTEEN') || auths(['wallet_walletRechargeApply_refund'])) ? '' : '3', auths(['wallet_walletRechargeApply_select_jz']) ? '' : '2', '1']"
placeholder="请选择饭卡类型" />
</el-form-item>
</el-col>
@@ -1,7 +1,8 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<el-form v-show="showSearch" ref="queryRef" :inline="true" :model="state.queryForm" @keyup.enter="getDataList">
<el-form v-show="showSearch" ref="queryRef" :inline="true" :model="state.queryForm"
@keyup.enter="getDataList">
<el-row>
<el-form-item style="width: 300px" label="用户" prop="userIds">
<select-user v-model="state.queryForm.userIds" placeholder="用户" />
@@ -10,60 +11,47 @@
<select-wallet-type v-model="state.queryForm.walletTypeId" placeholder="饭卡类型" clearable />
</el-form-item>
<el-form-item style="width: 200px" label="充值类型" prop="bizType">
<dict-select v-model="state.queryForm.bizType" dict-code="wallet_biz_recharge" placeholder="充值类型" />
<dict-select v-model="state.queryForm.bizType" dict-code="wallet_biz_recharge"
placeholder="充值类型" />
</el-form-item>
<el-form-item style="width: 450px" label="创建时间" prop="createTimeList">
<el-date-picker v-model="state.queryForm.createTimeList" value-format="YYYY-MM-DD HH:mm:ss" type="datetimerange" />
<el-date-picker v-model="state.queryForm.createTimeList" value-format="YYYY-MM-DD HH:mm:ss"
type="datetimerange" />
</el-form-item>
<el-form-item style="width: 450px" label="审核时间" prop="processTimeList">
<el-date-picker v-model="state.queryForm.processTimeList" value-format="YYYY-MM-DD HH:mm:ss" type="datetimerange" />
<el-date-picker v-model="state.queryForm.processTimeList" value-format="YYYY-MM-DD HH:mm:ss"
type="datetimerange" />
</el-form-item>
<el-form-item>
<el-button icon="Search" type="primary" @click="getDataList">{{ $t("common.queryBtn") }}</el-button>
<el-button icon="Search" type="primary" @click="getDataList">{{ $t("common.queryBtn")
}}</el-button>
<el-button icon="Refresh" @click="resetQuery">{{ $t("common.resetBtn") }}</el-button>
</el-form-item>
</el-row>
</el-form>
<el-row>
<div class="mb8" style="width: 100%">
<el-button icon="folder-add" type="primary" class="ml10" @click="uploadExcelRef.show()" v-auth="'wallet_walletRechargeApply_add'">
<el-button icon="folder-add" type="primary" class="ml10" @click="uploadExcelRef.show()"
v-auth="'wallet_walletRechargeApply_add'">
导 入
</el-button>
<el-button
v-if="false"
plain
:disabled="multiple"
icon="Delete"
type="primary"
v-auth="'wallet_walletRechargeApply_del'"
@click="handleDelete(selectObjs)"
>
<el-button v-if="false" plain :disabled="multiple" icon="Delete" type="primary"
v-auth="'wallet_walletRechargeApply_del'" @click="handleDelete(selectObjs)">
删除
</el-button>
<div class="flex justify-between items-center">
<el-tabs class="flex-1" v-model="activeName" @tab-click="handleClickTabItem">
<el-tab-pane v-for="v in tabItems" :key="v.id" :label="v.label" :name="v.value" />
</el-tabs>
<right-toolbar
v-model:showSearch="showSearch"
:export="'wallet_walletRechargeApply_export'"
@exportExcel="exportExcel"
class="ml10 mr20"
style="float: right"
@queryTable="getDataList"
/>
<right-toolbar v-model:showSearch="showSearch" :export="'wallet_walletRechargeApply_export'"
@exportExcel="exportExcel" class="ml10 mr20" style="float: right"
@queryTable="getDataList" />
</div>
</div>
</el-row>
<el-table
:data="state.dataList"
v-loading="state.loading"
border
:cell-style="tableStyle.cellStyle"
:header-cell-style="tableStyle.headerCellStyle"
@selection-change="selectionChangHandle"
@sort-change="sortChangeHandle"
>
<el-table :data="state.dataList" v-loading="state.loading" border :cell-style="tableStyle.cellStyle"
:header-cell-style="tableStyle.headerCellStyle" @selection-change="selectionChangHandle"
@sort-change="sortChangeHandle">
<el-table-column type="selection" width="40" align="center" />
<el-table-column type="index" label="#" width="80" />
<el-table-column prop="username" label="申请人" />
@@ -115,86 +103,48 @@
</div>
</template>
</el-table-column>
<el-table-column
label="操作"
v-auths="[
'wallet_walletRechargeApply_view',
'wallet_walletRechargeApply_apply',
'wallet_walletRechargeApply_edit',
'wallet_walletRechargeApply_del',
'wallet_walletRechargeApply_check',
]"
width="300"
fixed="right"
>
<el-table-column label="操作" v-auths="[
'wallet_walletRechargeApply_view',
'wallet_walletRechargeApply_apply',
'wallet_walletRechargeApply_edit',
'wallet_walletRechargeApply_del',
'wallet_walletRechargeApply_check',
]" width="300" fixed="right">
<template #default="{ row }">
<el-button
v-if="row.importTime"
icon="Document"
text
type="primary"
v-auth="'wallet_walletRechargeApply_view'"
@click="doInfo(row)"
>
<el-button v-if="row.importTime" icon="Document" text type="primary"
v-auth="'wallet_walletRechargeApply_view'" @click="doInfo(row)">
数据
</el-button>
<el-button
v-if="row.importTime && !row.processId"
icon="Connection"
text
type="primary"
v-auth="'wallet_walletRechargeApply_apply'"
@click="doApply(row)"
>
<el-button v-if="row.importTime && !row.processId" icon="Connection" text type="primary"
v-auth="'wallet_walletRechargeApply_apply'" @click="doApply(row)">
申请
</el-button>
<el-button
v-if="!row.processId"
icon="edit-pen"
text
type="primary"
v-auth="'wallet_walletRechargeApply_edit'"
@click="formDialogRef.openDialog(row.id)"
>
<el-button v-if="!row.processId" icon="edit-pen" text type="primary"
v-auth="'wallet_walletRechargeApply_edit'" @click="formDialogRef.openDialog(row.id)">
编辑
</el-button>
<el-button
v-if="row.isCheckUser && row.processStatus == '1'"
type="primary"
size="small"
link
icon="VideoPlay"
@click="deal(row)"
v-auth="'wallet_walletRechargeApply_check'"
>
<el-button v-if="row.isCheckUser && row.processStatus == '1'" type="primary" size="small" link
icon="VideoPlay" @click="deal(row)" v-auth="'wallet_walletRechargeApply_check'">
开始处理
</el-button>
<el-button
v-if="row.userId == userInfos?.user?.userId && [null, '1'].includes(row.processStatus)"
icon="delete"
text
type="primary"
v-auth="'wallet_walletRechargeApply_del'"
@click="handleDelete([row.id])"
>
icon="delete" text type="primary" v-auth="'wallet_walletRechargeApply_del'"
@click="handleDelete([row.id])">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle"
v-bind="state.pagination" />
</div>
<!-- 编辑、新增 -->
<form-dialog ref="formDialogRef" @refresh="getDataList(false)" />
<upload-excel
ref="uploadExcelRef"
title="充值导入"
url="/wallet/wallet-recharge-apply/read-excel"
temp-url="/admin/sys-file/local/file/wallet_recharge.xlsx"
@refreshDataList="getDataList(false)"
/>
<upload-excel ref="uploadExcelRef" title="充值导入" url="/wallet/wallet-recharge-apply/read-excel"
temp-url="/admin/sys-file/local/file/wallet_recharge.xlsx" @refreshDataList="getDataList(false)" />
<!-- 审批抽屉 -->
<process-drawer ref="processDrawerRef" @task-submit-event="taskSubmitEvent" />
@@ -307,6 +257,7 @@ const selectionChangHandle = (objs: { id: string }[]) => {
onMounted(async () => {
const { data } = await getDicts("check_status")
data.unshift({ label: "全部", value: null })
data.push({ label: "未提交", value: 99 })
tabItems.value = data
})
@@ -13,6 +13,7 @@
<el-date-picker v-model="state.queryForm.createTimeList" value-format="YYYY-MM-DD HH:mm:ss" type="datetimerange" />
</el-form-item>
<el-form-item>
<el-button icon="Search" type="primary" @click="getDataList">{{ $t("common.queryBtn") }}</el-button>
<el-button icon="Search" type="primary" @click="getDataList">{{ $t("common.queryBtn") }}</el-button>
<el-button icon="Refresh" @click="resetQuery">{{ $t("common.resetBtn") }}</el-button>
</el-form-item>
@@ -43,7 +44,7 @@
@sort-change="sortChangeHandle"
>
<el-table-column type="selection" width="40" align="center" />
<el-table-column type="index" label="#" width="40" />
<el-table-column type="index" label="#" width="50" />
<el-table-column prop="code" label="发票编号" />
<el-table-column prop="time" label="发票日期">
<template #default="{ row }">
@@ -69,17 +70,15 @@
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" />
<el-table-column prop="createTime" width="200" label="创建时间" />
<el-table-column label="操作" width="200" fixed="right">
<template #default="{ row }">
<!-- <el-button icon="edit-pen" text type="primary" v-auth="'wallet_walletRechargeInvoice_edit'"
@click="formDialogRef.openDialog(scope.row.id)">编辑</el-button> -->
<!-- v-if="['1'].includes(row.processStatus)" -->
<el-button
v-auth="'wallet_walletRechargeApply_print'"
icon="printer"
text
type="primary"
:loading="getReceiptDataLoading"
:loading="loading"
@click="previewInvoice(row)"
>
查看发票
@@ -138,7 +137,7 @@ const state: BasicTableProps = reactive<BasicTableProps>({
pageList: fetchList,
})
const printDialogRef = ref()
const getReceiptDataLoading = ref(false)
const loading = ref(false)
// table hook
const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, downBlobFile, tableStyle } = useTable(state)
@@ -183,7 +182,7 @@ const handleDelete = async (ids: string[]) => {
// 预览发票
const previewInvoice = async (row: any) => {
try {
getReceiptDataLoading.value = true
loading.value = true
if (!row.id) return useMessage().error("发票ID不存在")
const res = await getObj(row.id)
if (res.code == 0 && printDialogRef.value) return printDialogRef.value.openDialog(res.data, res.data.id)
@@ -191,7 +190,7 @@ const previewInvoice = async (row: any) => {
} catch (error: any) {
useMessage().error(error.msg)
} finally {
getReceiptDataLoading.value = false
loading.value = false
}
}
</script>
@@ -6,8 +6,7 @@
<div class="flex justify-between items-end mb-1">
<div></div>
<div>
{{ formatDate(new Date(receiptData.time), "YYYY年 mm月 dd日") || " 年 月 日".replace(/ /g, "&nbsp;&nbsp;")
}}
{{ formatDate(new Date(receiptData.time), "YYYY年 mm月 dd日") || " 年 月 日".replace(/ /g, "&nbsp;&nbsp;") }}
</div>
<span>
<span>No. </span>
@@ -20,8 +19,12 @@
<tr>
<td class="border border-gray-600 px-2 w-3/12 h-[0.75cm]">交款单位(或个人)</td>
<td class="border border-gray-600 px-2 w-9/12 h-[0.75cm] text-sm text-blue-800" colspan="4">
<input type="text" v-model="receiptData.deptOrUser"
class="caret-red-600 w-full h-full bg-transparent text-center" ref="deptOrUserInput" />
<input
type="text"
v-model="receiptData.deptOrUser"
class="caret-red-600 w-full h-full bg-transparent text-center"
ref="deptOrUserInput"
/>
</td>
</tr>
<tr>
@@ -58,10 +61,15 @@
<td class="border border-gray-600 px-2 w-1/6 h-[0.75cm]">收款单位<br />(盖章)</td>
<td class="border border-gray-600 px-2 text-left w-1/6 h-[0.75cm] text-sm text-blue-800">
<!-- <input type="text" v-model="receiptData.payeeDept" class="w-full h-full bg-transparent" /> -->
<img v-if="receiptData.picUrl" class="w-[2.5cm] h-[2.5cm] absolute -top-2 left-[140px]"
:class="{ stamping: isStamping }" draggable="false"
<img
v-if="receiptData.picUrl || isStamping"
class="w-[2.5cm] h-[2.5cm] absolute -top-2 left-[140px]"
:class="{ stamping: isStamping }"
draggable="false"
style="-webkit-user-drag: none; user-select: none; pointer-events: none"
oncontextmenu="return false" src="/@/assets/receiptStamp.png" />
oncontextmenu="return false"
src="/@/assets/receiptStamp.png"
/>
</td>
<td class="border border-gray-600 px-2 w-1/6 h-[0.75cm]">开票人<br />(签名)</td>
<td class="border border-gray-600 px-2 text-left w-1/6 h-[0.75cm] text-sm text-blue-800">
@@ -71,15 +79,16 @@
<td class="border border-gray-600 px-2 text-left align-text-top w-1/3 h-[0.75cm]">
<div class="flex">
<span class="whitespace-nowrap">备注:</span>
<textarea v-model="receiptData.remark"
class="flex-1 text-sm text-blue-800 w-full h-full my-1 bg-transparent resize-none overflow-y-hidden" />
<textarea
v-model="receiptData.remark"
class="flex-1 text-sm text-blue-800 w-full h-full my-1 bg-transparent resize-none overflow-y-hidden"
/>
</div>
</td>
</tr>
</table>
<div class="flex items-center absolute bottom-0 top-0 right-0">
<span class="text-gray-500 text-sm whitespace-nowrap"
style="writing-mode: vertical-rl; letter-spacing: 0.2em">
<span class="text-gray-500 text-sm whitespace-nowrap" style="writing-mode: vertical-rl; letter-spacing: 0.2em">
{{ "第一联 存根联".replace(/ /g, "&nbsp;&nbsp;&nbsp;&nbsp;") }}
</span>
</div>
@@ -87,20 +96,39 @@
</div>
<div class="h-6">
<el-progress :percentage="progressPercent" v-if="progressPercent > 30" :stroke-width="6" status="success"
striped striped-flow :duration="20" />
<el-progress
:percentage="progressPercent"
v-if="progressPercent > 30"
:stroke-width="6"
status="success"
striped
striped-flow
:duration="20"
/>
</div>
<template #footer>
<el-button @click="handleClose" :disabled="loading">关闭</el-button>
<el-button v-if="!receiptData.picUrl" v-auth="'wallet_walletRechargeApply_receiptStamp'" type="primary"
@click="stampReceipt" :disabled="loading">
<el-button
v-if="!receiptData.picUrl"
v-auth="'wallet_walletRechargeApply_receiptStamp'"
type="primary"
@click="stampReceipt"
:disabled="loading"
>
盖章
</el-button>
<el-button v-if="receiptData.picUrl" v-auth="'wallet_walletRechargeApply_back'" type="primary"
@click="backInvoice" :disabled="loadingBack">作废</el-button>
<el-button v-auth="'wallet_walletRechargeApply_receiptSave'" type="primary" @click="saveReceipt"
:disabled="loading">保存</el-button>
<el-button
v-if="receiptData.picUrl"
v-auth="'wallet_walletRechargeApply_back'"
type="primary"
plain
@click="backInvoice"
:disabled="loadingBack"
>
作废
</el-button>
<el-button v-auth="'wallet_walletRechargeApply_receiptSave'" type="primary" @click="saveReceipt" :disabled="loading">保存</el-button>
<el-button v-if="receiptData.picUrl" type="primary" @click="handlePrint" :disabled="loading">打印</el-button>
</template>
</el-dialog>
@@ -196,53 +224,58 @@ const backInvoice = async () => {
emit("refresh")
useMessage().success("作废成功")
} catch (error: any) {
console.error(error);
console.error(error)
useMessage().error(error.msg)
} finally {
loadingBack.value = false
}
}
// 生成图片并上传
const genImageUpload = async (): Promise<string | void> => {
// 生成图片
const genImage = async (): Promise<Blob | void | null> => {
if (receiptRef.value) {
const blob = await htmlToImage.toBlob(receiptRef.value, {
canvasWidth: 661.5,
canvasHeight: 359.1,
backgroundColor: "#ffffff",
pixelRatio: 6,
})
if (blob) {
try {
loading.value = true
const formData = new FormData()
formData.append("file", blob, "receipt.png")
const { code, data } = await request({
url: "/admin/sys-file/upload",
method: "post",
headers: {
"Content-Type": "multipart/form-data",
},
data: formData,
onUploadProgress: (progressEvent: any) => {
if (progressEvent.lengthComputable) {
progressPercent.value = Math.round((progressEvent.loaded * 100) / progressEvent.total)
}
},
})
if (code == 0) {
useMessage().success("盖章成功")
return data.url
}
useMessage().error(data.msg || "上传失败")
} catch (error) {
useMessage().error(error as string)
} finally {
loading.value = false
progressPercent.value = 30
const blob = await htmlToImage
.toBlob(receiptRef.value, {
canvasWidth: 661.5,
canvasHeight: 359.1,
backgroundColor: "#ffffff",
pixelRatio: 6,
})
.catch((error) => {
isStamping.value = false
}
}
return useMessage().error("图片生成错误")
})
return blob
}
}
// 图片上传
const uploadImage = async (blob: Blob): Promise<string | void> => {
try {
loading.value = true
const formData = new FormData()
formData.append("file", blob, "receipt.png")
const { code, data } = await request({
url: "/admin/sys-file/upload",
method: "post",
headers: {
"Content-Type": "multipart/form-data",
},
data: formData,
onUploadProgress: (progressEvent: any) => {
if (progressEvent.lengthComputable) {
progressPercent.value = Math.round((progressEvent.loaded * 100) / progressEvent.total)
}
},
})
if (code == 0) return data.url
useMessage().error(data.msg || "上传失败")
} catch (error) {
useMessage().error(error as string)
} finally {
loading.value = false
progressPercent.value = 30
isStamping.value = false
}
}
@@ -252,16 +285,19 @@ const stampReceipt = () => {
isStamping.value = true
timer = setTimeout(async () => {
const url = await genImageUpload()
if (url) {
receiptData.value.picUrl = url
await saveReceipt()
const blob = await genImage()
if (blob) {
const url = await uploadImage(blob)
if (url) {
receiptData.value.picUrl = url
await saveReceipt()
}
}
}, 1010)
}, 1030)
}
// 保存发票
const saveReceipt = async () => {
const saveReceipt = async (): Promise<void> => {
try {
loading.value = true
const { code, data } = await bindInvoice({