Commit 6093e6da by Jony.L

发票功能

parent e1c9423f
......@@ -47,6 +47,10 @@ export interface OrderVO {
afterSaleStatus?: number | null // 售后状态
refundPrice?: number | null // 退款金额
// ========== 发票基本信息 ==========
invoiceStatus?: number | null //开票状态
invoiceUrl?: String | null //发票链接
// ========== 营销基本信息 ==========
couponId?: number | null // 优惠劵编号
couponPrice?: number | null // 优惠劵减免金额
......@@ -171,6 +175,11 @@ export const pickUpOrder = async (id: number) => {
return await request.put({ url: `/trade/order/pick-up-by-id?id=${id}` })
}
//开具发票
export const issueInvoice = async (data: any) => {
return await request.put({ url: `/trade/order/issue-invoice`, data})
}
// 订单核销
export const pickUpOrderByVerifyCode = async (pickUpVerifyCode: string) => {
return await request.put({
......
......@@ -401,6 +401,25 @@ export const DeliveryTypeEnum = {
name: '到店自提'
}
}
/**
* 开票状态枚举
*/
export const InvoiceRequestEnum = {
UNINVOICED: {
type: 0,
name: '未开票'
},
INVOICING: {
type: 1,
name: '开票中'
},
INVOICED: {
type: 2,
name: '已开票'
}
}
/**
* 交易订单 - 状态
*/
......
......@@ -185,6 +185,7 @@ export enum DICT_TYPE {
TRADE_ORDER_STATUS = 'trade_order_status', // 订单 - 状态
TRADE_ORDER_ITEM_AFTER_SALE_STATUS = 'trade_order_item_after_sale_status', // 订单项 - 售后状态
TRADE_DELIVERY_TYPE = 'trade_delivery_type', // 配送方式
TRADE_INVOICE_STATUS = 'trade_invoice_status',
BROKERAGE_ENABLED_CONDITION = 'brokerage_enabled_condition', // 分佣模式
BROKERAGE_BIND_MODE = 'brokerage_bind_mode', // 分销关系绑定模式
BROKERAGE_BANK_NAME = 'brokerage_bank_name', // 佣金提现银行
......
......@@ -24,6 +24,9 @@
订单状态
</div>
<div :style="{ width: orderTableHeadWidthList[7] + 'px' }" class="flex justify-center">
开票状态
</div>
<div :style="{ width: orderTableHeadWidthList[8] + 'px' }" class="flex justify-center">
操作
</div>
</div>
......@@ -156,6 +159,11 @@
<dict-tag :type="DICT_TYPE.TRADE_ORDER_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column align="center" label="开票状态" width="120">
<template #default>
<dict-tag :type="DICT_TYPE.TRADE_INVOICE_STATUS" :value="scope.row.invoiceStatus" />
</template>
</el-table-column>
<el-table-column align="center" fixed="right" label="操作" width="160">
<template #default>
<slot :row="scope.row"></slot>
......@@ -236,7 +244,7 @@ const setOrderTableRef = (el: TableInstance) => {
tableHeadWidthAuto(el)
}
// 头部 col 宽度初始化
const orderTableHeadWidthList = ref([300, 150, 120, 120, 160, 120, 120, 160])
const orderTableHeadWidthList = ref([300, 150, 120, 120, 160, 120, 120, 120, 160])
// 头部宽度自适应
const tableHeadWidthAuto = (el: TableInstance) => {
const columns = el.store.states.columns.value
......
<template>
<Dialog v-model="dialogVisible" title="上传发票" width="45%">
<el-form-item label="发票地址" prop="invoiceUrl">
<UploadImg v-model="formData.invoiceUrl" />
<p class="upload-tips">
请上传 大小不超过 <span class="red-text">5MB</span> 格式为
<span class="red-text">png/jpg/jpeg</span>
的文件
</p>
</el-form-item>
<template #footer>
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
<el-button @click="dialogVisible = false">取 消</el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import * as TradeOrderApi from "@/api/mall/trade/order";
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const dialogVisible = ref(false) // 弹窗是否展示
const formRef = ref() // 表单 Ref
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const submitForm = async () => {
// 提交请求
formLoading.value = true
try {
const data = unref(formData)
await TradeOrderApi.issueInvoice(data)
message.success(t('common.updateSuccess'))
dialogVisible.value = false
// 发送操作成功的事件
emit('success', true)
} catch (error) {
console.error(error);
}finally {
formLoading.value = false
}
}
const formData = ref({
id: undefined, // 订单编号
invoiceStatus: undefined,
invoiceUrl: ''
})
const open = async (row: TradeOrderApi.OrderVO) => {
resetForm()
// 设置数据
formData.value.id = row.id
formData.value.invoiceStatus = row.invoiceStatus
formData.value.invoiceUrl = row.invoiceUrl
dialogVisible.value = true
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined, // 订单编号
invoiceStatus: undefined,
invoiceUrl: ''
}
formRef.value?.resetFields()
}
</script>
<style scoped lang="scss">
</style>
<template>
<!-- 图片查看弹窗 -->
<el-dialog
v-model="dialogVisible"
title="查看发票图片"
:width="`600px`"
:close-on-click-modal="false">
<div class="flex justify-center p-4">
<img
:src="formData.invoiceUrl"
alt="发票图片"
class="max-w-full max-h-[500px] object-contain"
@error="handleImageError"
/>
</div>
</el-dialog>
</template>
<script setup lang="ts">
import * as TradeOrderApi from "@/api/mall/trade/order";
const dialogVisible = ref(false) // 弹窗是否展示
const formData = ref({
id: undefined, // 订单编号
invoiceStatus: undefined,
invoiceUrl: ''
})
const open = async (row: TradeOrderApi.OrderVO) => {
resetForm()
// 设置数据
formData.value.id = row.id
formData.value.invoiceStatus = row.invoiceStatus
formData.value.invoiceUrl = row.invoiceUrl
dialogVisible.value = true
}
defineExpose({open}) // 提供 open 方法,用于打开弹窗
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined, // 订单编号
invoiceStatus: undefined,
invoiceUrl: ''
}
}
const handleImageError = (e) => {
e.target.src = 'https://picsum.photos/600/400?grayscale&blur=2'; // 占位图
e.target.alt = '图片加载失败';
};
</script>
<style scoped lang="scss">
</style>
......@@ -201,6 +201,23 @@
<Icon icon="ep:takeaway-box" />
发货
</el-dropdown-item>
<!-- 如果订单开票状态为【未开票】【开票中】,则展示【开票】按钮-->
<el-dropdown-item
v-if="
row.invoiceStatus === InvoiceRequestEnum.UNINVOICED.type ||
row.invoiceStatus === InvoiceRequestEnum.INVOICING.type
"
command="issueInvoice"
>
<Icon icon="ep:takeaway-box" />
开票
</el-dropdown-item>
<el-dropdown-item
v-if="row.invoiceStatus === InvoiceRequestEnum.INVOICED.type"
command="viewInvoice">
<Icon icon="ep:takeaway-box"/>
展示发票
</el-dropdown-item>
<el-dropdown-item command="remark">
<Icon icon="ep:chat-line-square" />
备注
......@@ -224,6 +241,8 @@
<!-- 各种操作的弹窗 -->
<OrderDeliveryForm ref="deliveryFormRef" @success="getList" />
<OrderUpdateRemarkForm ref="updateRemarkForm" @success="getList" />
<OrderIssueInvoiceForm ref="issueInvoiceFormRef" @success="getList" />
<OrderViewInvoiceForm ref="viewInvoiceFormRef" @success="getList" />
</template>
<script lang="ts" setup>
......@@ -234,7 +253,7 @@ import * as TradeOrderApi from '@/api/mall/trade/order'
import * as PickUpStoreApi from '@/api/mall/trade/delivery/pickUpStore'
import { DICT_TYPE, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
import * as DeliveryExpressApi from '@/api/mall/trade/delivery/express'
import { DeliveryTypeEnum, TradeOrderStatusEnum } from '@/utils/constants'
import {DeliveryTypeEnum, InvoiceRequestEnum, TradeOrderStatusEnum} from '@/utils/constants'
import { OrderTableColumn } from './components'
defineOptions({ name: 'TradeOrder' })
......@@ -327,6 +346,8 @@ const openDetail = (id: number) => {
/** 操作分发 */
const deliveryFormRef = ref()
const updateRemarkForm = ref()
const issueInvoiceFormRef = ref()
const viewInvoiceFormRef = ref()
const handleCommand = (command: string, row: TradeOrderApi.OrderVO) => {
switch (command) {
case 'remark':
......@@ -335,6 +356,12 @@ const handleCommand = (command: string, row: TradeOrderApi.OrderVO) => {
case 'delivery':
deliveryFormRef.value?.open(row)
break
case 'issueInvoice':
issueInvoiceFormRef.value?.open(row)
break
case 'viewInvoice':
viewInvoiceFormRef.value?.open(row)
break
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment