Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
d4f0205c4d
9 files changed
+597
-552
No files matched your search
@@ -8,6 +8,20 @@ export function invoiceBack(query: any) {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发票申请
|
||||
* @param id 发票id
|
||||
* @param picUrl 发票图片
|
||||
* @returns
|
||||
*/
|
||||
export function apply(data: any) {
|
||||
return request({
|
||||
url: "/wallet/walletRechargeInvoice/apply",
|
||||
method: "post",
|
||||
data: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据申请id获取发票详情
|
||||
* @param id 申请id
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
<template>
|
||||
<div class="w-full h-full p-1">
|
||||
<el-row class="my-1">
|
||||
<el-button type="primary" @click="pushEvent">新增</el-button>
|
||||
<el-button @click="removeSelectRowEvent">删除选中</el-button>
|
||||
</el-row>
|
||||
<el-row class="mb-2">
|
||||
<el-button type="primary" @click="pushEvent">新增</el-button>
|
||||
</el-row>
|
||||
|
||||
<vxe-table
|
||||
ref="editableTableRef"
|
||||
border
|
||||
show-overflow
|
||||
max-height="380"
|
||||
:edit-rules="validRules"
|
||||
:column-config="{ resizable: true }"
|
||||
:row-config="{ isHover: true }"
|
||||
:resizable-config="{ dragMode: 'fixed' }"
|
||||
:data="auxiliaryCodeList"
|
||||
:edit-config="{
|
||||
<vxe-table
|
||||
ref="tableRef"
|
||||
show-overflow
|
||||
max-height="340"
|
||||
height="340"
|
||||
:edit-rules="validRules"
|
||||
:column-config="{ resizable: true }"
|
||||
:row-config="{ isHover: true }"
|
||||
:resizable-config="{ dragMode: 'fixed' }"
|
||||
:data="auxiliaryCodeList"
|
||||
:edit-config="{
|
||||
trigger: 'click',
|
||||
mode: 'cell',
|
||||
beforeEditMethod({ row, column }:any) {
|
||||
@@ -26,136 +24,121 @@
|
||||
return true
|
||||
},
|
||||
}"
|
||||
size="mini"
|
||||
align="center"
|
||||
>
|
||||
<vxe-column type="checkbox" width="40" fixed="left" />
|
||||
<vxe-column type="seq" width="50" fixed="left" />
|
||||
<vxe-column field="unit" title="单位" :edit-render="{}">
|
||||
<template #edit="{ row, $rowIndex }">
|
||||
<el-select v-model="row.unitId" @change="handleUnitIdChange(row.unitId, $rowIndex)">
|
||||
<template v-for="item in computedSmErpUnitEntityList">
|
||||
<el-option :label="item.unit" :value="item.id" />
|
||||
</template>
|
||||
</el-select>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.unitId">{{ computedSmErpUnitEntityList?.find((item: rowVU) => item.id === row.unitId)?.unit }}</span>
|
||||
<span v-else style="color: #c0c4cf">请选择</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="taste" title="口味">
|
||||
<template #default="{ row }">
|
||||
{{ computedSmErpUnitEntityList?.find((item: rowVU) => item.id === row.unitId)?.taste }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="barCode" title="辅助条码" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input v-model.trim="row.barCode" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</div>
|
||||
size="mini"
|
||||
align="center"
|
||||
>
|
||||
<vxe-column type="seq" width="50" fixed="left" />
|
||||
<!-- <vxe-column type="checkbox" width="40" fixed="left" /> -->
|
||||
<vxe-column field="unit" title="单位" :edit-render="{}">
|
||||
<template #edit="{ row, $rowIndex }">
|
||||
<el-select v-model="row.unitId" @change="handleUnitIdChange(row.unitId, $rowIndex)">
|
||||
<template v-for="item in unitSelectOptions">
|
||||
<el-option :label="item.unit" :value="item.id">
|
||||
<span class="float-left">单位:{{ item.unit }}</span>
|
||||
<span class="float-right ml-4">口味:{{ item.taste }}</span>
|
||||
</el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.unitId">{{ unitSelectOptions?.find((item: rowVU) => item.id === row.unitId)?.unit }}</span>
|
||||
<span v-else style="color: #c0c4cf">请选择</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="taste" title="口味">
|
||||
<template #default="{ row }">
|
||||
{{ unitSelectOptions?.find((item: rowVU) => item.id === row.unitId)?.taste }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="barCode" title="辅助条码" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input v-model.trim="row.barCode" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column title="操作">
|
||||
<template #default="scope">
|
||||
<el-popconfirm title="是否删除?" @confirm="removeRow(scope.$rowIndex)">
|
||||
<template #reference><el-button size="small">删除</el-button></template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { nanoid } from "nanoid"
|
||||
import { useMessage } from "/@/hooks/message"
|
||||
import { type rowVU } from "./package-unit.vue"
|
||||
import { useMessage } from "/@/hooks/message"
|
||||
|
||||
export interface rowVC {
|
||||
id: string
|
||||
unitId: string
|
||||
unit: string
|
||||
barCode: string
|
||||
taste: string
|
||||
isNew?: boolean
|
||||
barCode: string
|
||||
}
|
||||
|
||||
const auxiliaryCodeList = defineModel("modelValue", {
|
||||
default: [
|
||||
{
|
||||
id: nanoid(5),
|
||||
unitId: "",
|
||||
unit: "",
|
||||
taste: "",
|
||||
barCode: "",
|
||||
},
|
||||
],
|
||||
})
|
||||
const props = withDefaults(defineProps<{ smErpUnitEntityList?: rowVU[] }>(), { smErpUnitEntityList: [] as any })
|
||||
const auxiliaryCodeList = defineModel<any>("modelValue", { default: [] })
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
smErpUnitEntityList?: rowVU[]
|
||||
}>(),
|
||||
{
|
||||
smErpUnitEntityList: [] as any,
|
||||
},
|
||||
)
|
||||
|
||||
const editableTableRef = ref()
|
||||
const tableRef = ref()
|
||||
|
||||
const validRules = {
|
||||
// unit: [{ required: true, message: "包装单位不能为空", trigger: "blur" }],
|
||||
// barCode: [{ required: true, message: "条码不能为空", trigger: "blur" }],
|
||||
}
|
||||
|
||||
// 底部表格行新增
|
||||
// 底部新增行
|
||||
const pushEvent = () => {
|
||||
if (props.smErpUnitEntityList?.length === 0) return useMessage().warning("请先添加包装单位")
|
||||
|
||||
const newRow: rowVC = {
|
||||
id: nanoid(5),
|
||||
id: "tmp_" + nanoid(5),
|
||||
unitId: "",
|
||||
unit: "",
|
||||
barCode: "",
|
||||
taste: "",
|
||||
isNew: true,
|
||||
barCode: "",
|
||||
}
|
||||
auxiliaryCodeList.value.push(newRow)
|
||||
nextTick(() => {
|
||||
const $table = editableTableRef.value
|
||||
const $table = tableRef.value
|
||||
if ($table) {
|
||||
$table.setEditRow(newRow)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 删除行
|
||||
const removeRow = (rowIndex: number) => {
|
||||
auxiliaryCodeList.value.splice(rowIndex, 1)
|
||||
}
|
||||
|
||||
// 可选择的包装单位下拉菜单
|
||||
const unitSelectOptions = computed(() => props.smErpUnitEntityList?.filter((item: rowVU) => item.unit))
|
||||
|
||||
// 包装单位行删除时清除辅助条码中选择该包装单位的行
|
||||
watch(
|
||||
() => props.smErpUnitEntityList?.length,
|
||||
() => {
|
||||
auxiliaryCodeList.value = auxiliaryCodeList.value.filter((codeItem: rowVC) =>
|
||||
props.smErpUnitEntityList?.some((item: rowVU) => codeItem.unitId === item.id),
|
||||
)
|
||||
(newValue, oldValue) => {
|
||||
if (newValue! < oldValue!) {
|
||||
auxiliaryCodeList.value = auxiliaryCodeList.value.filter((codeItem: rowVC) =>
|
||||
props.smErpUnitEntityList?.some((item: rowVU) => codeItem.unitId === item.id),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// 计算辅助条码中可选择的包装单位下拉菜单
|
||||
const computedSmErpUnitEntityList = computed(() => props.smErpUnitEntityList?.filter((item: rowVU) => item.unit))
|
||||
|
||||
// 包装单位下拉选择变化
|
||||
const handleUnitIdChange = (unitId: string, rowIndex: number) => {
|
||||
const unitItem = computedSmErpUnitEntityList.value?.find((item: rowVU) => item.id == unitId)
|
||||
const unitItem = unitSelectOptions.value?.find((item: rowVU) => item.id == unitId)
|
||||
;(auxiliaryCodeList.value[rowIndex] as any).unit = unitItem?.unit
|
||||
;(auxiliaryCodeList.value[rowIndex] as any).taste = unitItem?.taste
|
||||
}
|
||||
|
||||
// 删除选中的行
|
||||
const removeSelectRowEvent = () => {
|
||||
const $table = editableTableRef.value
|
||||
if ($table) {
|
||||
const selectRecords = $table.getCheckboxRecords()
|
||||
if (selectRecords.length > 0) {
|
||||
auxiliaryCodeList.value = auxiliaryCodeList.value.filter((item: rowVC) => !selectRecords.some((row: rowVC) => row.id === item.id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 校验可编辑表格 成功返回 true 失败返回 false
|
||||
// const editableTableValidate = async () => {
|
||||
// const tableValidate = async () => {
|
||||
// // 全量校验
|
||||
// const $table = editableTableRef.value
|
||||
// const $table = tableRef.value
|
||||
// if ($table) {
|
||||
// const errMap = await $table.validate(true)
|
||||
// if (errMap) {
|
||||
@@ -169,6 +152,6 @@ const removeSelectRowEvent = () => {
|
||||
// }
|
||||
|
||||
// defineExpose({
|
||||
// editableTableValidate,
|
||||
// tableValidate,
|
||||
// })
|
||||
</script>
|
||||
@@ -1,84 +1,112 @@
|
||||
<template>
|
||||
<el-row>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="货号" prop="productCode">
|
||||
<el-input v-model.trim="form.productCode" placeholder="请输入货号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="商品名称" prop="productName">
|
||||
<el-input v-model.trim="form.productName" placeholder="请输入商品名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="货商" prop="supplierId">
|
||||
<SelectSupermarketSupplier v-model="form.supplierId" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="商品分类" prop="categoryId">
|
||||
<el-select v-model="form.categoryId" placeholder="请选择商品分类">
|
||||
<el-option v-for="item in categoryOptions" :key="item?.id" :label="item?.name" :value="item?.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="品牌" prop="brandId">
|
||||
<el-select v-model="form.brandId" placeholder="请选择品牌">
|
||||
<el-option v-for="item in brandOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="商品性质" prop="productNature">
|
||||
<el-select v-model="form.productNature" placeholder="请选择商品性质">
|
||||
<el-option :value="item.value" :label="item.label" v-for="(item, index) in supermarket_nature" :key="index" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="商品封面图" prop="picUrl">
|
||||
<upload-img v-model:imageUrl="form.picUrl" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="商品状态" prop="status">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio :label="item.value" v-for="(item, index) in status" border :key="index">{{ item.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="货商" prop="supplierId">
|
||||
<SelectSupermarketSupplier v-model="form.supplierId" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="商品分类" prop="categoryId">
|
||||
<el-select v-model="form.categoryId" placeholder="请选择商品分类">
|
||||
<el-option v-for="item in categoryOptions" :key="item?.id" :label="item?.name" :value="item?.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="商品性质" prop="productNature">
|
||||
<el-select v-model="form.productNature" placeholder="请选择商品性质">
|
||||
<el-option :value="item.value" :label="item.label" v-for="(item, index) in supermarket_nature" :key="index" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="品牌" prop="brandId">
|
||||
<el-select v-model="form.brandId" placeholder="请选择品牌">
|
||||
<el-option v-for="item in brandOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="排序字段" prop="sort">
|
||||
<el-input-number :min="0" :max="1000" :precision="0" v-model="form.sort" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="毛利率" prop="grossMargin">
|
||||
<el-input-number v-model="form.grossMargin" :min="0" :precision="2" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="产地" prop="origin">
|
||||
<el-input v-model.trim="form.origin" placeholder="请输入产地" />
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="商品封面图" prop="picUrl">
|
||||
<upload-img v-model:imageUrl="form.picUrl" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-col :span="16" class="mb20">
|
||||
<el-form-item label="商品产地" prop="origin">
|
||||
<el-input v-model.trim="form.origin" placeholder="请输入商品产地" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<hr />
|
||||
</el-col>
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="条码" prop="barCode">
|
||||
<el-input v-model.trim="form.barCode" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="规格" prop="spec">
|
||||
<el-input v-model.trim="form.spec" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="单位" prop="unit">
|
||||
<el-input v-model.trim="form.unit" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="内装数" prop="packageNum">
|
||||
<el-input-number v-model="form.packageNum" :min="0" :precision="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="进价(元)" prop="purchasePrice">
|
||||
<el-input-number v-model="form.purchasePrice" :min="0" :precision="2" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="零售价(元)" prop="retailPrice">
|
||||
<el-input-number v-model="form.retailPrice" :min="0" :precision="2" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="促销价(元)" prop="promotionPrice">
|
||||
<el-input-number v-model="form.promotionPrice" :min="0" :precision="2" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="成本价(元)" prop="costPrice">
|
||||
<el-input-number v-model="form.costPrice" :min="0" :precision="2" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="单位状态" prop="unitStatus">
|
||||
<el-radio-group v-model="form.unitStatus">
|
||||
<el-radio label="0" border>正常</el-radio>
|
||||
@@ -86,31 +114,6 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="内装数" prop="packageNum">
|
||||
<el-input-number v-model="form.packageNum" :min="0" :precision="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="进价(元)" prop="purchasePrice">
|
||||
<el-input-number v-model="form.purchasePrice" :min="0" :precision="2" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="零售价(元)" prop="retailPrice">
|
||||
<el-input-number v-model="form.retailPrice" :min="0" :precision="2" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="促销价(元)" prop="promotionPrice">
|
||||
<el-input-number v-model="form.promotionPrice" :min="0" :precision="2" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="成本价(元)" prop="costPrice">
|
||||
<el-input-number v-model="form.costPrice" :min="0" :precision="2" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,33 +1,31 @@
|
||||
<template>
|
||||
<div class="w-full h-full p-1">
|
||||
<el-row class="my-1">
|
||||
<el-button type="primary" @click="pushEvent()">新增</el-button>
|
||||
<el-button @click="removeSelectRowEvent">删除选中</el-button>
|
||||
<el-tooltip effect="light" placement="right">
|
||||
<template #content>
|
||||
<el-alert class="w-[500px] h-24" type="warning" show-icon :closable="false">
|
||||
<p>
|
||||
注:内装数据必须为该商品的最小售卖的基本单位,否则无法完成库存数量转换,影响erp库存自动扣减操作。
|
||||
例如:一瓶矿泉水内装填'1',为售卖的最小基础单位,如果想按箱卖,在继续添加包装单位为箱,内装为24
|
||||
</p>
|
||||
</el-alert>
|
||||
</template>
|
||||
<el-icon class="text-xl my-auto ml-4 text-yellow-600"><WarningFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</el-row>
|
||||
<el-row class="mb-2">
|
||||
<el-button type="primary" @click="pushEvent()">新增</el-button>
|
||||
<el-tooltip effect="light" placement="right">
|
||||
<template #content>
|
||||
<el-alert class="w-[500px] h-24" type="warning" show-icon :closable="false">
|
||||
<p>
|
||||
注:内装数据必须为该商品的最小售卖的基本单位,否则无法完成库存数量转换,影响erp库存自动扣减操作。
|
||||
例如:一瓶矿泉水内装填'1',为售卖的最小基础单位,如果想按箱卖,在继续添加包装单位为箱,内装为24
|
||||
</p>
|
||||
</el-alert>
|
||||
</template>
|
||||
<el-icon class="text-xl my-auto ml-4 text-yellow-600"><WarningFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</el-row>
|
||||
|
||||
<vxe-table
|
||||
ref="editableTableRef"
|
||||
border
|
||||
show-overflow
|
||||
max-height="380"
|
||||
:radio-config="{ highlight: true }"
|
||||
:column-config="{ resizable: true }"
|
||||
:row-config="{ isHover: true }"
|
||||
:resizable-config="{ dragMode: 'fixed' }"
|
||||
:data="packageUnitList"
|
||||
:edit-rules="validRules"
|
||||
:edit-config="{
|
||||
<vxe-table
|
||||
ref="tableRef"
|
||||
show-overflow
|
||||
max-height="340"
|
||||
height="340"
|
||||
:edit-rules="validRules"
|
||||
:radio-config="{ highlight: true }"
|
||||
:column-config="{ resizable: true }"
|
||||
:row-config="{ isHover: true }"
|
||||
:resizable-config="{ dragMode: 'fixed' }"
|
||||
:data="packageUnitList"
|
||||
:edit-config="{
|
||||
trigger: 'click',
|
||||
mode: 'cell',
|
||||
beforeEditMethod({ row, column }:any) {
|
||||
@@ -38,133 +36,156 @@
|
||||
return true
|
||||
},
|
||||
}"
|
||||
size="mini"
|
||||
align="center"
|
||||
>
|
||||
<vxe-column type="seq" width="50" fixed="left" />
|
||||
<vxe-column type="checkbox" width="40" fixed="left" />
|
||||
<vxe-column type="radio" title="基础单位" fixed="left" />
|
||||
<vxe-column field="barCode" title="条码" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input v-model.trim="row.barCode" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="spec" title="规格" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input v-model.trim="row.spec" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="unit" title="单位名称" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input v-model.trim="row.unit" @input="(value: string | number) => handleUnitInput(row, value)" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="taste" title="口味" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input v-model.trim="row.taste" @input="(value: string | number) => handleTasteInput(row, value)" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="status" title="状态" :edit-render="{}">
|
||||
<template #edit="{ row }">
|
||||
<el-select v-model="row.status">
|
||||
<el-option label="正常" value="0" />
|
||||
<el-option label="停销" value="1" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.status == '0'">正常</span>
|
||||
<span v-else-if="row.status == '1'">停销</span>
|
||||
<span v-else style="color: #c0c4cf">请选择</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="packageNum" title="内装数" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input-number v-model="row.packageNum" controls-position="right" :min="1" :precision="0" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="purchasePrice" title="进价(元)" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input-number v-model="row.purchasePrice" controls-position="right" :min="0" :precision="2" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="retailPrice" title="零售价(元)" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input-number v-model="row.retailPrice" controls-position="right" :min="0.01" :precision="2" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="promotionPrice" title="促销价(元)" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input-number v-model="row.promotionPrice" controls-position="right" :min="0" :precision="2" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="costPrice" title="成本价(元)" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input-number v-model="row.costPrice" controls-position="right" :min="0" :precision="2" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</div>
|
||||
size="mini"
|
||||
align="center"
|
||||
>
|
||||
<vxe-column type="seq" width="50" fixed="left" />
|
||||
<!-- <vxe-column type="checkbox" width="40" fixed="left" /> -->
|
||||
<vxe-column type="radio" title="基础单位" fixed="left" />
|
||||
<vxe-column field="barCode" title="条码" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input v-model.trim="row.barCode" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="spec" title="规格" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input v-model.trim="row.spec" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="unit" title="单位名称" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="slotParams">
|
||||
<el-input v-model.trim="slotParams.row.unit" @input="slotInputChange(slotParams)" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="taste" title="口味" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="slotParams">
|
||||
<el-input v-model.trim="slotParams.row.taste" @input="slotInputChange(slotParams)" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="status" title="状态" :edit-render="{}">
|
||||
<template #edit="{ row }">
|
||||
<el-select v-model="row.status">
|
||||
<el-option label="正常" value="0" />
|
||||
<el-option label="停销" value="1" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.status == '0'">正常</span>
|
||||
<span v-else-if="row.status == '1'">停销</span>
|
||||
<span v-else style="color: #c0c4cf">请选择</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="packageNum" title="内装数" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input-number v-model="row.packageNum" controls-position="right" :min="1" :precision="0" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="purchasePrice" title="进价(元)" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input-number v-model="row.purchasePrice" controls-position="right" :min="0" :precision="2" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="retailPrice" title="零售价(元)" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input-number v-model="row.retailPrice" controls-position="right" :min="0.01" :precision="2" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="promotionPrice" title="促销价(元)" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input-number v-model="row.promotionPrice" controls-position="right" :min="0" :precision="2" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="costPrice" title="成本价(元)" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
|
||||
<template #edit="{ row }">
|
||||
<el-input-number v-model="row.costPrice" controls-position="right" :min="0" :precision="2" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column title="操作">
|
||||
<template #default="scope">
|
||||
<el-popconfirm title="是否删除?" @confirm="removeRow(scope.$rowIndex)">
|
||||
<template #reference><el-button size="small">删除</el-button></template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { VxeTablePropTypes } from "vxe-table"
|
||||
import { nanoid } from "nanoid"
|
||||
import { useMessage } from "/@/hooks/message"
|
||||
|
||||
export interface rowVU {
|
||||
id: string
|
||||
barCode: string
|
||||
spec: string
|
||||
unit: string
|
||||
unitId?: string
|
||||
status: string
|
||||
packageNum: number
|
||||
purchasePrice: number
|
||||
retailPrice: number
|
||||
promotionPrice: number
|
||||
costPrice: number
|
||||
isNew?: boolean
|
||||
isBase?: boolean | null
|
||||
flag?: string
|
||||
taste?: string
|
||||
}
|
||||
|
||||
const packageUnitList = defineModel<rowVU[]>("modelValue", {
|
||||
default: [
|
||||
const packageUnitList = defineModel<rowVU[]>("modelValue", { default: [] })
|
||||
|
||||
const tableRef = ref()
|
||||
|
||||
const validRules = ref<VxeTablePropTypes.EditRules<rowVU>>({
|
||||
barCode: [{ required: true, message: "不能为空" }],
|
||||
unit: [
|
||||
{ required: true, message: "不能为空" },
|
||||
{
|
||||
id: nanoid(5),
|
||||
barCode: "",
|
||||
spec: "",
|
||||
unit: "",
|
||||
status: "0",
|
||||
packageNum: 1,
|
||||
purchasePrice: 0,
|
||||
retailPrice: 0.01,
|
||||
promotionPrice: 0,
|
||||
costPrice: 0,
|
||||
taste: "",
|
||||
validator({ cellValue, row, rowIndex }) {
|
||||
if (
|
||||
cellValue &&
|
||||
packageUnitList.value
|
||||
.filter((item: rowVU, index: number) => rowIndex != index && item.taste == row.taste)
|
||||
.some((v: rowVU) => v.unit == row.unit)
|
||||
)
|
||||
return new Error("该包装单位的口味已存在")
|
||||
},
|
||||
},
|
||||
],
|
||||
status: [{ required: true, message: "不能为空" }],
|
||||
packageNum: [{ required: true, message: "不能为空" }],
|
||||
retailPrice: [{ required: true, type: "number", min: 0.01, message: "不能为0" }],
|
||||
purchasePrice: [{ required: true, message: "不能为空" }],
|
||||
taste: [
|
||||
{
|
||||
validator({ cellValue, row, rowIndex }) {
|
||||
if (
|
||||
cellValue &&
|
||||
packageUnitList.value
|
||||
.filter((item: rowVU, index: number) => rowIndex != index && item.taste == row.taste)
|
||||
.some((v: rowVU) => v.unit == row.unit)
|
||||
)
|
||||
return new Error("该包装单位的口味已存在")
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
const editableTableRef = ref()
|
||||
const validRules = {
|
||||
barCode: [{ required: true, message: "条码不能为空", trigger: "blur" }],
|
||||
// spec: [{ required: true, message: "规格不能为空", trigger: "blur" }],
|
||||
unit: [{ required: true, message: "单位不能为空", trigger: "blur" }],
|
||||
status: [{ required: true, message: "状态不能为空", trigger: "blur" }],
|
||||
packageNum: [{ required: true, message: "内装数不能为空", trigger: "blur" }],
|
||||
retailPrice: [{ required: true, type: "number", min: 0.01, message: "零售价不能为0" }],
|
||||
purchasePrice: [{ required: true, message: "进价不能为空", trigger: "blur" }],
|
||||
// promotionPrice: [{ required: true, message: "促销价不能为空", trigger: "blur" }],
|
||||
// 自定义编辑模板的input校验
|
||||
const slotInputChange = (slotParams: any) => {
|
||||
const $table = tableRef.value
|
||||
if ($table) {
|
||||
$table.updateStatus(slotParams)
|
||||
}
|
||||
}
|
||||
|
||||
// 底部表格行新增
|
||||
// 底部新增行
|
||||
const pushEvent = (row?: rowVU | undefined) => {
|
||||
const newRow = {} as rowVU
|
||||
if (row) {
|
||||
Object.assign(newRow, row)
|
||||
} else {
|
||||
row = {
|
||||
id: nanoid(5),
|
||||
id: "tmp_" + nanoid(5),
|
||||
barCode: "",
|
||||
spec: "",
|
||||
unit: "",
|
||||
@@ -175,51 +196,44 @@ const pushEvent = (row?: rowVU | undefined) => {
|
||||
promotionPrice: 0,
|
||||
costPrice: 0,
|
||||
taste: "",
|
||||
isNew: true,
|
||||
}
|
||||
Object.assign(newRow, row)
|
||||
}
|
||||
packageUnitList.value.push(newRow)
|
||||
nextTick(() => {
|
||||
const $table = editableTableRef.value
|
||||
const $table = tableRef.value
|
||||
if ($table) {
|
||||
$table.setEditRow(newRow)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 删除选中的行
|
||||
const removeSelectRowEvent = () => {
|
||||
const $table = editableTableRef.value
|
||||
// 删除行
|
||||
const removeRow = (rowIndex: number) => {
|
||||
packageUnitList.value.splice(rowIndex, 1)
|
||||
}
|
||||
|
||||
// 设置单选的行
|
||||
const setRadioRow = (index: number) => {
|
||||
const $table = tableRef.value
|
||||
if ($table) {
|
||||
const selectRecords = $table.getCheckboxRecords()
|
||||
if (selectRecords.length > 0) {
|
||||
packageUnitList.value = packageUnitList.value.filter((item: rowVU) => !selectRecords.some((row: rowVU) => row.id === item.id))
|
||||
}
|
||||
$table.setRadioRow(packageUnitList.value[index])
|
||||
}
|
||||
}
|
||||
|
||||
// 获取单选的行
|
||||
const getRadioRow = () => {
|
||||
const $table = editableTableRef.value
|
||||
const $table = tableRef.value
|
||||
if ($table) {
|
||||
const currRadioRow = $table.getRadioRecord()
|
||||
return currRadioRow
|
||||
}
|
||||
}
|
||||
|
||||
// 设置单选的行
|
||||
const setRadioRow = (index: number) => {
|
||||
const $table = editableTableRef.value
|
||||
if ($table) {
|
||||
$table.setRadioRow(packageUnitList.value[index])
|
||||
}
|
||||
}
|
||||
|
||||
// 校验可编辑表格 成功返回 true 失败返回 false
|
||||
const editableTableValidate = async () => {
|
||||
// 校验表格 成功返回 true 失败返回 false
|
||||
const tableValidate = async () => {
|
||||
// 全量校验
|
||||
const $table = editableTableRef.value
|
||||
const $table = tableRef.value
|
||||
if ($table) {
|
||||
const errMap = await $table.validate(true)
|
||||
if (errMap) {
|
||||
@@ -232,32 +246,10 @@ const editableTableValidate = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 口味字段值改变
|
||||
const handleTasteInput = (row: rowVU, value: string | number) => {
|
||||
if (
|
||||
packageUnitList.value.filter((item: rowVU) => item.id != row.id && item.unit == row.unit).some((item: rowVU) => item.taste == value)
|
||||
) {
|
||||
useMessage().warning("该包装单位的口味已存在")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 单位字段值改变
|
||||
const handleUnitInput = (row: rowVU, value: string | number) => {
|
||||
if (
|
||||
packageUnitList.value.filter((item: rowVU) => item.id != row.id && item.unit == row.unit).some((item: rowVU) => item.taste == row.taste)
|
||||
) {
|
||||
useMessage().warning("该包装单位的口味已存在")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
editableTableValidate,
|
||||
getRadioRow,
|
||||
tableValidate,
|
||||
setRadioRow,
|
||||
getRadioRow,
|
||||
pushEvent,
|
||||
})
|
||||
</script>
|
||||
@@ -1,18 +1,18 @@
|
||||
<template>
|
||||
<el-row>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="期初库存" prop="stock" class="flex w-full h-full">
|
||||
<el-input-number v-model="stock" :min="0" :precision="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="库存上限" prop="inventoryUpperLimit">
|
||||
<el-input-number v-model="inventoryUpperLimit" :min="0" :precision="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-col :span="8" class="mb20">
|
||||
<el-form-item label="库存下限" prop="inventoryLowerLimit">
|
||||
<el-input-number v-model="inventoryLowerLimit" :min="0" :precision="0" />
|
||||
</el-form-item>
|
||||
|
||||
@@ -137,6 +137,7 @@ const handleFileSuccess = (response: any) => {
|
||||
* 提交表单,触发上传
|
||||
*/
|
||||
const submitFileForm = () => {
|
||||
state.upload.isUploading = true
|
||||
uploadRef.value.submit()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<el-dialog width="80%" :title="form.id ? '编辑' : '新增'" v-model="visible" :close-on-click-modal="false" draggable>
|
||||
<el-form ref="formRef" :model="form" :rules="dataRules" label-width="150px" v-loading="loading">
|
||||
<el-dialog width="90%" :title="form.id ? '编辑' : '新增'" v-model="visible" :close-on-click-modal="false" draggable>
|
||||
<el-form ref="formRef" :model="form" :rules="dataRules" label-width="100px" v-loading="loading">
|
||||
<el-tabs class="el-tabs" v-model="tabPaneActiveName" @tab-change="handleTabChange" type="border-card">
|
||||
<el-tab-pane class="el-tab-pane" label="基础信息" name="基础信息">
|
||||
<base-info v-model="form" />
|
||||
@@ -16,15 +16,15 @@
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane class="el-tab-pane" label="辅助条码" name="辅助条码">
|
||||
<auxiliary-code :smErpUnitEntityList="form.smErpUnitEntityList" v-model="form.smErpAuxiliaryCodeEntityList" />
|
||||
<auxiliary-code v-model="form.smErpAuxiliaryCodeEntityList" :smErpUnitEntityList="form.smErpUnitEntityList" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button v-if="currentTabPaneIndex != 0" type="primary" @click="currentTabPaneIndex--" :disabled="loading">上一步</el-button>
|
||||
<el-button v-if="currentTabPaneIndex != tabPaneEnum.length - 1" type="primary" @click="nextStep">下一步</el-button>
|
||||
<el-button v-if="currentTabPaneIndex == tabPaneEnum.length - 1" type="primary" @click="onSubmit" :loading="loading">提 交</el-button>
|
||||
<el-button v-if="tabPaneActiveIndex != 0" type="primary" @click="previousStep" :disabled="loading">上一步</el-button>
|
||||
<el-button v-if="tabPaneActiveIndex != tabPaneName.length - 1" type="primary" @click="nextStep">下一步</el-button>
|
||||
<el-button v-if="tabPaneActiveIndex == tabPaneName.length - 1" type="primary" @click="onSubmit" :loading="loading">提 交</el-button>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
@@ -43,15 +43,14 @@ import { nanoid } from "nanoid"
|
||||
|
||||
const emit = defineEmits(["refresh"])
|
||||
|
||||
const formRef = ref()
|
||||
const packageUnitRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const tabPaneEnum = ["基础信息", "包装单位", "库存", "辅助条码"]
|
||||
const currentTabPaneIndex = ref(0)
|
||||
const tabPaneActiveName = computed(() => tabPaneEnum[currentTabPaneIndex.value])
|
||||
const formRef = ref()
|
||||
const packageUnitRef = ref()
|
||||
const tabPaneName = ["基础信息", "包装单位", "库存", "辅助条码"]
|
||||
const tabPaneActiveName = ref(tabPaneName[0])
|
||||
const tabPaneActiveIndex = ref(0)
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive<any>({
|
||||
id: "",
|
||||
merchantId: "",
|
||||
@@ -83,9 +82,8 @@ const form = reactive<any>({
|
||||
promotionPrice: 0,
|
||||
costPrice: 0,
|
||||
})
|
||||
|
||||
// 基本信息的金额转为单位分
|
||||
const formatedBaseFormMoney = computed(() => {
|
||||
const formatedStorePrice = computed(() => {
|
||||
return {
|
||||
grossMargin: storePrice(form.grossMargin),
|
||||
purchasePrice: storePrice(form.purchasePrice),
|
||||
@@ -95,7 +93,7 @@ const formatedBaseFormMoney = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
// 表单校验规则
|
||||
const dataRules = {
|
||||
productNature: [{ required: true, message: "请选择商品性质", trigger: "blur" }],
|
||||
merchantId: [{ required: true, message: "商户不能为空", trigger: "blur" }],
|
||||
@@ -122,11 +120,56 @@ const dataRules = {
|
||||
// costPrice: [{ required: true, message: "成本价不能为空", trigger: "blur" }],
|
||||
}
|
||||
|
||||
// tab栏切换
|
||||
const handleTabChange = (name: TabPaneName) => {
|
||||
tabPaneActiveIndex.value = tabPaneName.findIndex((item) => item === name)
|
||||
setDefaultPackageUnit()
|
||||
}
|
||||
|
||||
// 上一步
|
||||
const previousStep = () => {
|
||||
tabPaneActiveIndex.value--
|
||||
tabPaneActiveName.value = tabPaneName[tabPaneActiveIndex.value]
|
||||
setDefaultPackageUnit()
|
||||
}
|
||||
|
||||
// 下一步
|
||||
const nextStep = () => {
|
||||
tabPaneActiveIndex.value++
|
||||
tabPaneActiveName.value = tabPaneName[tabPaneActiveIndex.value]
|
||||
setDefaultPackageUnit()
|
||||
}
|
||||
|
||||
// 默认设置一行基础包装单位
|
||||
const setDefaultPackageUnit = () => {
|
||||
if (!form.id && tabPaneActiveIndex.value == 1) {
|
||||
const isFlagRowExist = form.smErpUnitEntityList.some((item: rowVU) => item.flag === "defaultPackageUnitRow")
|
||||
if (isFlagRowExist) return
|
||||
const row = {
|
||||
id: "tmp_" + nanoid(5),
|
||||
barCode: form.barCode,
|
||||
spec: form.spec,
|
||||
unit: form.unit,
|
||||
status: form.unitStatus,
|
||||
packageNum: form.packageNum,
|
||||
purchasePrice: form.purchasePrice,
|
||||
retailPrice: form.retailPrice,
|
||||
promotionPrice: form.promotionPrice,
|
||||
costPrice: form.costPrice,
|
||||
flag: "defaultPackageUnitRow",
|
||||
}
|
||||
packageUnitRef.value.pushEvent(row)
|
||||
packageUnitRef.value.setRadioRow(0) // 自动设置基础包装单位的radio单选行
|
||||
}
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (id: string) => {
|
||||
visible.value = true
|
||||
currentTabPaneIndex.value = 0
|
||||
tabPaneActiveIndex.value = 0
|
||||
tabPaneActiveName.value = tabPaneName[tabPaneActiveIndex.value]
|
||||
form.id = ""
|
||||
visible.value = true
|
||||
|
||||
// 重置表单数据
|
||||
resetForm()
|
||||
|
||||
@@ -144,10 +187,10 @@ const openDialog = async (id: string) => {
|
||||
const getsupermarketSpuData = async (id: string) => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getObj(id)
|
||||
if (res.code === 0) {
|
||||
res.data.smErpUnitEntityList = res.data.smErpUnitEntityList.map((item: rowVU) => {
|
||||
// 格式化金额数据
|
||||
const { code, data } = await getObj(id)
|
||||
if (code === 0) {
|
||||
data.smErpUnitEntityList = data.smErpUnitEntityList.map((item: rowVU) => {
|
||||
// 格式化金额
|
||||
item.retailPrice = parseFloat(displayPrice(item.retailPrice, ""))
|
||||
item.promotionPrice = parseFloat(displayPrice(item.promotionPrice, ""))
|
||||
item.purchasePrice = parseFloat(displayPrice(item.purchasePrice, ""))
|
||||
@@ -156,12 +199,12 @@ const getsupermarketSpuData = async (id: string) => {
|
||||
})
|
||||
|
||||
Object.assign(form, {
|
||||
...res.data,
|
||||
grossMargin: parseFloat(displayPrice(res.data.grossMargin, "")),
|
||||
retailPrice: parseFloat(displayPrice(res.data.retailPrice, "")),
|
||||
promotionPrice: parseFloat(displayPrice(res.data.promotionPrice, "")),
|
||||
purchasePrice: parseFloat(displayPrice(res.data.purchasePrice, "")),
|
||||
costPrice: parseFloat(displayPrice(res.data.costPrice, "")),
|
||||
...data,
|
||||
grossMargin: parseFloat(displayPrice(data.grossMargin, "")),
|
||||
retailPrice: parseFloat(displayPrice(data.retailPrice, "")),
|
||||
promotionPrice: parseFloat(displayPrice(data.promotionPrice, "")),
|
||||
purchasePrice: parseFloat(displayPrice(data.purchasePrice, "")),
|
||||
costPrice: parseFloat(displayPrice(data.costPrice, "")),
|
||||
})
|
||||
}
|
||||
} catch (error: any) {
|
||||
@@ -178,44 +221,6 @@ const resetForm = () => {
|
||||
form.smErpAuxiliaryCodeEntityList = []
|
||||
}
|
||||
|
||||
// tab栏切换
|
||||
const handleTabChange = (name: TabPaneName) => {
|
||||
currentTabPaneIndex.value = tabPaneEnum.findIndex((item) => item === name)
|
||||
if (form.id) return
|
||||
setDefaultPackageUnit()
|
||||
}
|
||||
|
||||
// 下一步
|
||||
const nextStep = () => {
|
||||
currentTabPaneIndex.value++
|
||||
if (form.id) return
|
||||
setDefaultPackageUnit()
|
||||
}
|
||||
|
||||
// 默认设置一行基础包装单位
|
||||
const setDefaultPackageUnit = () => {
|
||||
if (currentTabPaneIndex.value == 1) {
|
||||
const isFlagRowExist = form.smErpUnitEntityList.some((item: rowVU) => item.flag === "defaultAddedPackageUnit")
|
||||
if (isFlagRowExist) return
|
||||
const row = {
|
||||
id: nanoid(5),
|
||||
barCode: form.barCode,
|
||||
spec: form.spec,
|
||||
unit: form.unit,
|
||||
status: form.unitStatus,
|
||||
packageNum: form.packageNum,
|
||||
purchasePrice: form.purchasePrice,
|
||||
retailPrice: form.retailPrice,
|
||||
promotionPrice: form.promotionPrice,
|
||||
costPrice: form.costPrice,
|
||||
isNew: true,
|
||||
flag: "defaultAddedPackageUnit",
|
||||
}
|
||||
packageUnitRef.value.pushEvent(row)
|
||||
packageUnitRef.value.setRadioRow(0) // 自动设置基础包装单位的radio单选行
|
||||
}
|
||||
}
|
||||
|
||||
// 整理包装单位列表
|
||||
const settlePackageUnitList = () => {
|
||||
const curRadioRowUnit = packageUnitRef.value.getRadioRow()
|
||||
@@ -227,15 +232,12 @@ const settlePackageUnitList = () => {
|
||||
} else {
|
||||
item.isBase = false
|
||||
}
|
||||
if (item.id.startsWith("tmp_")) item.id = ""
|
||||
// 转换金额单位
|
||||
item.costPrice = storePrice(item.costPrice)
|
||||
item.promotionPrice = storePrice(item.promotionPrice)
|
||||
item.purchasePrice = storePrice(item.purchasePrice)
|
||||
item.retailPrice = storePrice(item.retailPrice)
|
||||
if (item.isNew) {
|
||||
item.id = ""
|
||||
delete item.isNew
|
||||
}
|
||||
return item
|
||||
})
|
||||
}
|
||||
@@ -246,13 +248,8 @@ const settleAuxiliaryCode = () => {
|
||||
return smErpAuxiliaryCodeEntityList
|
||||
.filter((item: rowVC) => item.unitId)
|
||||
.map((item: rowVC) => {
|
||||
const curPackageUnitItem = form.smErpUnitEntityList.find((unitItem: any) => unitItem.id == item.unitId)
|
||||
|
||||
if (item.isNew) {
|
||||
item.id = ""
|
||||
if (curPackageUnitItem?.isNew) item.unitId = ""
|
||||
delete item.isNew
|
||||
}
|
||||
if (item.id.startsWith("tmp_")) item.id = ""
|
||||
if (item.unitId.startsWith("tmp_")) item.unitId = ""
|
||||
return item
|
||||
})
|
||||
}
|
||||
@@ -262,27 +259,21 @@ const onSubmit = async () => {
|
||||
const valid = await formRef.value.validate().catch(() => {})
|
||||
if (!valid) return useMessage().warning("基础信息或库存必填项未填写完整")
|
||||
if (!form.smErpUnitEntityList || form.smErpUnitEntityList.length <= 0) return useMessage().warning("请添加包装单位")
|
||||
if (!(await packageUnitRef.value.editableTableValidate())) return useMessage().warning("包装单位必填项未填写完整")
|
||||
if (!(await packageUnitRef.value.tableValidate())) return useMessage().warning("包装单位必填项未填写完整 且 相同包装单位的口味不能相同")
|
||||
if (!packageUnitRef.value.getRadioRow()) return useMessage().warning("请选择基础包装单位")
|
||||
|
||||
// if (!form.smErpAuxiliaryCodeEntityList || form.smErpAuxiliaryCodeEntityList.length <= 0) return useMessage().warning("请添加辅助条码")
|
||||
// if (!(await auxiliaryCodeRef.value.editableTableValidate())) return useMessage().warning("辅助条码必填项未填写完整")
|
||||
|
||||
console.log("未整理-包装单位", form.smErpUnitEntityList)
|
||||
console.log("未整理-辅助条码", form.smErpAuxiliaryCodeEntityList)
|
||||
|
||||
const smErpAuxiliaryCodeEntityList = settleAuxiliaryCode()
|
||||
const smErpUnitEntityList = settlePackageUnitList()
|
||||
try {
|
||||
loading.value = true
|
||||
const _pa = {
|
||||
...form,
|
||||
...formatedBaseFormMoney.value,
|
||||
...formatedStorePrice.value,
|
||||
smErpAuxiliaryCodeEntityList,
|
||||
smErpUnitEntityList,
|
||||
}
|
||||
|
||||
console.log("提交的数据", _pa)
|
||||
// console.log("提交的数据", _pa)
|
||||
|
||||
const res = form.id ? await putObj(_pa) : await addObj(_pa)
|
||||
if (res.code === 0) {
|
||||
|
||||
@@ -1,110 +1,136 @@
|
||||
<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="申请用户" />
|
||||
</el-form-item>
|
||||
<el-form-item style="width: 300px" label="交款单位或个人" prop="deptOrUser">
|
||||
<el-input v-model="state.queryForm.deptOrUser" clearable placeholder="交款单位或个人" />
|
||||
</el-form-item>
|
||||
<el-form-item style="width: 300px" label="发票状态" prop="userIds">
|
||||
<dict-select v-model="state.queryForm.status" dict-code="recharge_invoice_status" />
|
||||
</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-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="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>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
:export="'wallet_walletRechargeInvoice_export'"
|
||||
@exportExcel="exportExcel"
|
||||
class="ml10 mr20"
|
||||
style="float: right"
|
||||
@queryTable="getDataList"
|
||||
></right-toolbar>
|
||||
<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_walletRechargeInvoice_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="50" />
|
||||
<el-table-column prop="code" label="发票编号" />
|
||||
<el-table-column prop="time" label="发票日期">
|
||||
<el-table-column prop="code" min-width="100" label="发票编号" />
|
||||
<el-table-column prop="time" min-width="120" label="发票日期">
|
||||
<template #default="{ row }">
|
||||
{{ parseTime(row.time, "{y}-{m}-{d}") }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="deptOrUser" label="交款单位或个人" />
|
||||
<el-table-column prop="totalPrice" label="合计人民币">
|
||||
<el-table-column prop="deptOrUser" min-width="140" label="交款单位或个人" />
|
||||
<el-table-column prop="totalPrice" min-width="120" label="合计人民币">
|
||||
<template #default="{ row }">
|
||||
{{ displayPrice(row.totalPrice) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="payeeUser" label="收款人" />
|
||||
<el-table-column prop="payeeDept" label="收款单位" />
|
||||
<el-table-column prop="status" label="发票状态">
|
||||
<el-table-column prop="payeeUser" min-width="120" label="收款人" show-overflow-tooltip />
|
||||
<el-table-column prop="payeeDept" min-width="120" label="收款单位" show-overflow-tooltip />
|
||||
<el-table-column prop="processStatus" width="100" label="审核状态">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :options="check_status" :value="row.processStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="发票状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :options="recharge_invoice_status" :value="row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="payeeDept" label="发票下载">
|
||||
<el-table-column prop="stampPicUrl" min-width="120" label="发票图片">
|
||||
<template #default="{ row }">
|
||||
<preview-image :src="row.picUrl" download :downloadName="`${row.deptOrUser}-${row.payeeDept}-发票-${row.updateTime}`" />
|
||||
<preview-image :src="row.stampPicUrl" download
|
||||
:downloadName="`${row.code}-${row.deptOrUser}-${row.payeeDept}-发票-${row.updateTime}`" />
|
||||
</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">
|
||||
<el-table-column prop="remark" label="备注" show-overflow-tooltip />
|
||||
<el-table-column width="250" label="时间">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-auth="'wallet_walletRechargeApply_print'"
|
||||
icon="printer"
|
||||
text
|
||||
type="primary"
|
||||
:disabled="loading"
|
||||
@click="previewInvoice(row)"
|
||||
>
|
||||
查看发票
|
||||
</el-button>
|
||||
<el-button icon="delete" text type="primary" v-auth="'wallet_walletRechargeInvoice_del'" @click="handleDelete([row.id])">
|
||||
删除
|
||||
</el-button>
|
||||
<div class="flex justify-start">
|
||||
<span>创建时间:</span>
|
||||
<span>{{ row.createTime }} </span>
|
||||
</div>
|
||||
<div class="flex justify-start">
|
||||
<span>申请时间:</span>
|
||||
<span>{{ row.applyTime ?? "---" }} </span>
|
||||
</div>
|
||||
<div class="flex justify-start">
|
||||
<span>审批时间:</span>
|
||||
<span>{{ row.processTime ?? "---" }} </span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="300" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div class="flex">
|
||||
<el-button v-auth="'wallet_walletRechargeApply_print'" icon="printer" text type="primary"
|
||||
:disabled="loading" @click="previewInvoice(row)">
|
||||
查看发票
|
||||
</el-button>
|
||||
<!-- row.isCheckUser && -->
|
||||
<el-button v-if="row.processStatus == '1'" type="primary" link icon="VideoPlay"
|
||||
:disabled="loading" @click="deal(row)">
|
||||
开始处理
|
||||
</el-button>
|
||||
<el-button icon="delete" text type="primary" v-auth="'wallet_walletRechargeInvoice_del'"
|
||||
@click="handleDelete([row.id])">
|
||||
删除
|
||||
</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" />
|
||||
</div>
|
||||
|
||||
<upload-excel
|
||||
ref="uploadExcelRef"
|
||||
title="导入"
|
||||
url="/wallet/wallet-recharge-apply/read-topup-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-topup-excel"
|
||||
temp-url="/admin/sys-file/local/file/wallet_recharge.xlsx" @refreshDataList="getDataList(false)" />
|
||||
|
||||
<!-- 编辑、新增 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList(false)" />
|
||||
|
||||
<!-- 发票预览 -->
|
||||
<print-dialog ref="printDialogRef" @refresh="getDataList(false)" />
|
||||
|
||||
<!-- 审批抽屉 -->
|
||||
<process-drawer ref="processDrawerRef" @task-submit-event="taskSubmitEvent" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -116,21 +142,27 @@ import { displayPrice } from "/@/utils/formatMoney"
|
||||
import { parseTime } from "/@/utils/formatTime"
|
||||
import { useDict } from "/@/hooks/dict"
|
||||
import { getObj } from "/@/api/wallet/wallet-recharge-invoice"
|
||||
import ProcessDrawer from "/@/components/processDrawer/index.vue"
|
||||
import { getDicts } from "/@/api/admin/dict"
|
||||
|
||||
// 引入组件
|
||||
const FormDialog = defineAsyncComponent(() => import("./form.vue"))
|
||||
const PrintDialog = defineAsyncComponent(() => import("./print-dialog.vue"))
|
||||
|
||||
const { recharge_invoice_status } = useDict("recharge_invoice_status")
|
||||
const { recharge_invoice_status, check_status } = useDict("recharge_invoice_status", "check_status")
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const uploadExcelRef = ref()
|
||||
// 搜索变量
|
||||
const queryRef = ref()
|
||||
const processDrawerRef = ref()
|
||||
const showSearch = ref(true)
|
||||
// 多选变量
|
||||
const selectObjs = ref([]) as any
|
||||
const multiple = ref(true)
|
||||
const activeName = ref()
|
||||
const tabItems = ref<any>([{}])
|
||||
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {},
|
||||
@@ -146,6 +178,7 @@ const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, do
|
||||
const resetQuery = () => {
|
||||
// 清空搜索条件
|
||||
queryRef.value?.resetFields()
|
||||
state.queryForm.processStatus = ""
|
||||
// 清空多选
|
||||
selectObjs.value = []
|
||||
getDataList()
|
||||
@@ -162,6 +195,19 @@ const selectionChangHandle = (objs: { id: string }[]) => {
|
||||
multiple.value = !objs.length
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const { data } = await getDicts("check_status")
|
||||
data.unshift({ label: "全部", value: null })
|
||||
data.push({ label: "未提交", value: 99 })
|
||||
tabItems.value = data
|
||||
})
|
||||
|
||||
// tab点击切换
|
||||
const handleClickTabItem = (e: any) => {
|
||||
state.queryForm.processStatus = tabItems.value[e.index].value
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 删除操作
|
||||
const handleDelete = async (ids: string[]) => {
|
||||
try {
|
||||
@@ -193,4 +239,15 @@ const previewInvoice = async (row: any) => {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 执行审批
|
||||
const deal = (row: any) => {
|
||||
if (!row.processId) return useMessage().info("流程id不存在")
|
||||
processDrawerRef.value.openProcessDrawer(row)
|
||||
}
|
||||
|
||||
// 审批提交
|
||||
const taskSubmitEvent = () => {
|
||||
getDataList()
|
||||
}
|
||||
</script>
|
||||
@@ -1,6 +1,8 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="预览" width="800px" :close-on-click-modal="false" draggable destroy-on-close>
|
||||
<div id="receiptRef" ref="receiptRef" class="w-[17.5cm] h-[9.5cm] border border-gray-400 p-6 bg-[#EBE1C622]">
|
||||
<dict-tag class="mb-2" :options="check_status" :value="receiptData.processStatus" />
|
||||
|
||||
<div v-loading="loading" id="receiptRef" ref="receiptRef" class="w-[17.5cm] h-[9.5cm] border border-gray-400 p-6 bg-[#EBE1C622]">
|
||||
<div class="text-center mx-auto w-[10cm] text-3xl font-bold">浦江县行政事业单位食堂统一收款收据</div>
|
||||
|
||||
<div class="flex justify-between items-end mb-1">
|
||||
@@ -24,6 +26,7 @@
|
||||
v-model="receiptData.deptOrUser"
|
||||
class="caret-red-600 w-full h-full bg-transparent text-center"
|
||||
ref="deptOrUserInput"
|
||||
maxlength="30"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -61,15 +64,14 @@
|
||||
<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 || isStamping"
|
||||
<!-- <img
|
||||
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"
|
||||
/>
|
||||
/> -->
|
||||
</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">
|
||||
@@ -81,7 +83,8 @@
|
||||
<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"
|
||||
maxlength="12"
|
||||
class="flex-1 text-sm text-blue-800 w-full h-full bg-transparent resize-none overflow-y-hidden"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
@@ -95,21 +98,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h-6">
|
||||
<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
|
||||
<!-- <el-button
|
||||
v-if="!receiptData.picUrl"
|
||||
v-auth="'wallet_walletRechargeApply_receiptStamp'"
|
||||
type="primary"
|
||||
@@ -117,19 +108,20 @@
|
||||
:disabled="loading"
|
||||
>
|
||||
盖章
|
||||
</el-button>
|
||||
</el-button> -->
|
||||
<el-button
|
||||
v-if="receiptData.picUrl"
|
||||
v-if="receiptData.processStatus == '2' || receiptData.processStatus == '3'"
|
||||
v-auth="'wallet_walletRechargeApply_back'"
|
||||
type="primary"
|
||||
plain
|
||||
@click="backInvoice"
|
||||
:disabled="loadingBack"
|
||||
:disabled="loading"
|
||||
>
|
||||
作废
|
||||
</el-button>
|
||||
<el-button v-if="!receiptData.processStatus" type="primary" :disabled="loading" @click="applyStamp">申请审批</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>
|
||||
<el-button v-if="receiptData.stampPicUrl" type="warning" @click="handlePrint" :disabled="loading">打印</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
@@ -142,9 +134,8 @@ import request from "/@/utils/request"
|
||||
import { formatDate } from "/@/utils/formatTime"
|
||||
import { displayPrice } from "/@/utils/formatMoney"
|
||||
import printJS from "print-js"
|
||||
import { bindInvoice, invoiceBack, getObj } from "/@/api/wallet/wallet-recharge-invoice"
|
||||
|
||||
const emit = defineEmits(["refresh"])
|
||||
import { bindInvoice, invoiceBack, getObj, apply } from "/@/api/wallet/wallet-recharge-invoice"
|
||||
import { useDict } from "/@/hooks/dict"
|
||||
|
||||
interface ReceiptData {
|
||||
id: string
|
||||
@@ -158,14 +149,18 @@ interface ReceiptData {
|
||||
remark: string
|
||||
totalPriceCnStr: string
|
||||
picUrl: string
|
||||
stampPicUrl: string
|
||||
processStatus: string | null
|
||||
}
|
||||
|
||||
const emit = defineEmits(["refresh"])
|
||||
|
||||
const { check_status } = useDict("check_status")
|
||||
let timer
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const loadingBack = ref(false)
|
||||
const receiptRef = ref<HTMLElement | null>(null)
|
||||
const deptOrUserInput = ref<HTMLInputElement | null>(null)
|
||||
let timer
|
||||
const isStamping = ref(false) // 盖章动画开关
|
||||
const receiptData = ref<ReceiptData>({
|
||||
id: "",
|
||||
@@ -179,9 +174,9 @@ const receiptData = ref<ReceiptData>({
|
||||
payeeUser: "", // 开票人
|
||||
remark: "", // 备注
|
||||
picUrl: "", // 发票图片地址
|
||||
stampPicUrl: "", // 盖过章的发票图片地址
|
||||
processStatus: "", // 审批状态
|
||||
})
|
||||
const applyId = ref<string>()
|
||||
const progressPercent = ref(30)
|
||||
const receiptDataItems = computed(() => {
|
||||
try {
|
||||
const itemJson = JSON.parse(receiptData.value.itemJson)
|
||||
@@ -198,7 +193,7 @@ const totalPrice = computed(() => displayPrice(receiptData.value.totalPrice))
|
||||
const openDialog = (data: ReceiptData, id: string) => {
|
||||
visible.value = true
|
||||
receiptData.value = data
|
||||
applyId.value = id
|
||||
receiptData.value.id = id
|
||||
isStamping.value = false
|
||||
timer = setTimeout(() => {
|
||||
deptOrUserInput.value?.focus()
|
||||
@@ -212,11 +207,7 @@ const handleClose = () => {
|
||||
|
||||
// 发票作废
|
||||
const backInvoice = async () => {
|
||||
if (!receiptData.value.picUrl) {
|
||||
useMessage().error("请先盖章")
|
||||
return
|
||||
}
|
||||
loadingBack.value = true
|
||||
loading.value = true
|
||||
try {
|
||||
await invoiceBack({ id: receiptData.value.id })
|
||||
const res = await getObj(receiptData.value.id)
|
||||
@@ -227,7 +218,7 @@ const backInvoice = async () => {
|
||||
console.error(error)
|
||||
useMessage().error(error.msg)
|
||||
} finally {
|
||||
loadingBack.value = false
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,50 +242,36 @@ const genImage = async (): Promise<Blob | void | null> => {
|
||||
|
||||
// 图片上传
|
||||
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
|
||||
}
|
||||
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,
|
||||
})
|
||||
if (code == 0) return data.url
|
||||
useMessage().error(data.msg || "上传失败")
|
||||
}
|
||||
|
||||
// 盖章并上传发票图片并保存
|
||||
const stampReceipt = () => {
|
||||
loading.value = true
|
||||
isStamping.value = true
|
||||
// const stampReceipt = () => {
|
||||
// loading.value = true
|
||||
// isStamping.value = true
|
||||
|
||||
timer = setTimeout(async () => {
|
||||
const blob = await genImage()
|
||||
if (blob) {
|
||||
const url = await uploadImage(blob)
|
||||
if (url) {
|
||||
receiptData.value.picUrl = url
|
||||
await saveReceipt()
|
||||
}
|
||||
}
|
||||
}, 1030)
|
||||
}
|
||||
// timer = setTimeout(async () => {
|
||||
// const blob = await genImage()
|
||||
// if (blob) {
|
||||
// const url = await uploadImage(blob)
|
||||
// if (url) {
|
||||
// receiptData.value.picUrl = url
|
||||
// await saveReceipt()
|
||||
// }
|
||||
// }
|
||||
// }, 1030)
|
||||
// }
|
||||
|
||||
// 保存发票
|
||||
const saveReceipt = async (): Promise<void> => {
|
||||
@@ -303,7 +280,7 @@ const saveReceipt = async (): Promise<void> => {
|
||||
const { code, data } = await bindInvoice({
|
||||
...receiptData.value,
|
||||
deptOrUser: receiptData.value.deptOrUser,
|
||||
applyId: applyId.value,
|
||||
applyId: receiptData.value.id,
|
||||
})
|
||||
if (code == 0) {
|
||||
emit("refresh")
|
||||
@@ -318,6 +295,33 @@ const saveReceipt = async (): Promise<void> => {
|
||||
}
|
||||
}
|
||||
|
||||
// 申请盖章审批
|
||||
const applyStamp = async () => {
|
||||
await useMessage().delConfirm("是否提交审批")
|
||||
if (receiptData.value.processStatus == "1") return useMessage().warning("你已提交过申请,请勿重复提交")
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const blob = await genImage()
|
||||
if (!blob) return useMessage().success("图片生成失败")
|
||||
const picUrl = await uploadImage(blob)
|
||||
if (!picUrl) return useMessage().success("图片上传失败")
|
||||
|
||||
const { code, msg } = await apply({ id: receiptData.value.id, picUrl })
|
||||
if (code == 0) {
|
||||
useMessage().success("申请成功")
|
||||
emit("refresh")
|
||||
visible.value = false
|
||||
return
|
||||
}
|
||||
useMessage().error(msg || "申请失败")
|
||||
} catch (error) {
|
||||
useMessage().error(error as string)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 打印
|
||||
const handlePrint = async () => {
|
||||
if (receiptRef.value) {
|
||||
|
||||
Reference in new issue
Block a user