|
@@ -0,0 +1,279 @@
|
|
|
+<script setup lang="ts">
|
|
|
+import { computed, ref, watch } from "vue";
|
|
|
+import { dayjs, ElForm, ElInput, ElMessage, UploadProps } from "element-plus";
|
|
|
+import { ticketFormItems } from "../config/_details";
|
|
|
+import { invoceRules } from "../config/_rules";
|
|
|
+import { useResponseHandle } from "/@/hooks/core/useAsync";
|
|
|
+import { httpImageUpload, baseUrl } from "/@/api/other";
|
|
|
+import { useUserStore } from "/@/store/modules/user";
|
|
|
+import { inv_type_list } from "/@/utils/status";
|
|
|
+import { INPUT_MAX_LENGTH } from "/@/utils/global";
|
|
|
+
|
|
|
+const emit = defineEmits(["change"]);
|
|
|
+
|
|
|
+const visible = ref(false);
|
|
|
+const fileList = ref([]);
|
|
|
+
|
|
|
+//支持的图片格式
|
|
|
+const imgs = ref<any[]>([]);
|
|
|
+const invType = ref("1");
|
|
|
+const loading = ref(false);
|
|
|
+const types = ["png", "jpg", "bmp", "jpeg"].map(format => "image/" + format);
|
|
|
+const formItems = computed(() => ticketFormItems[invType.value] || []);
|
|
|
+const rules = ref({ ...invoceRules });
|
|
|
+const formRef = ref<InstanceType<typeof ElForm>>(null);
|
|
|
+const showScanInput = computed(() => invType.value === "1");
|
|
|
+const scanInputValue = ref("");
|
|
|
+
|
|
|
+const formData = ref<Record<string, string>>({
|
|
|
+ currentValue: ""
|
|
|
+});
|
|
|
+
|
|
|
+const userStore = useUserStore();
|
|
|
+const responseHandle = useResponseHandle();
|
|
|
+
|
|
|
+//图片上传前判断类型大小尺寸
|
|
|
+const onBeforeReturnImageUpload: UploadProps["beforeUpload"] = ({
|
|
|
+ type,
|
|
|
+ size
|
|
|
+}) => {
|
|
|
+ if (!types.includes(type)) {
|
|
|
+ ElMessage.error("请上传jpg.png.bmp.jpeg类型图片");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (size / 1024 / 1024 > 1) {
|
|
|
+ ElMessage.error("图片大小超过1M");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+function handleClose() {
|
|
|
+ imgs.value = [];
|
|
|
+ fileList.value = [];
|
|
|
+ formData.value = {};
|
|
|
+}
|
|
|
+
|
|
|
+//保存采购回票
|
|
|
+function handleSave() {
|
|
|
+ formRef.value.validate(async isValid => {
|
|
|
+ if (!isValid) return;
|
|
|
+ if (!invType.value) return ElMessage.error("请选择申请类型");
|
|
|
+
|
|
|
+ if (invType.value === "2") {
|
|
|
+ if (!imgs.value.length) return ElMessage.error("请选择上传的图片");
|
|
|
+ if (imgs.value.length > 100)
|
|
|
+ return ElMessage.error("上传图片不能超过100张");
|
|
|
+ }
|
|
|
+
|
|
|
+ emit(
|
|
|
+ "change",
|
|
|
+ invType.value === "2"
|
|
|
+ ? imgs.value
|
|
|
+ : {
|
|
|
+ ...formData.value,
|
|
|
+ invType: invType.value
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ visible.value = false;
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function handleScanKeydown(evt: KeyboardEvent) {
|
|
|
+ const { keyCode } = evt;
|
|
|
+
|
|
|
+ console.log(keyCode);
|
|
|
+ if (keyCode !== 13) return;
|
|
|
+
|
|
|
+ //校验扫描枪值是否含有中文逗号
|
|
|
+ if (scanInputValue.value.indexOf(",") >= 0) {
|
|
|
+ ElMessage.error("不能包含中文逗号");
|
|
|
+ return (scanInputValue.value = "");
|
|
|
+ }
|
|
|
+
|
|
|
+ const [_, invoiceType, ...chunks] = scanInputValue.value.split(",");
|
|
|
+ const [invCode, invNumber, subtotal_amount, open_time, checkNumber] = chunks;
|
|
|
+
|
|
|
+ const year = open_time.slice(0, 4);
|
|
|
+ const month = open_time.slice(4, 6);
|
|
|
+ const day = open_time.slice(6);
|
|
|
+
|
|
|
+ formData.value = {
|
|
|
+ invoiceType,
|
|
|
+ invCode,
|
|
|
+ subtotal_amount,
|
|
|
+ open_time: dayjs(`${year}-${month}-${day}`).format("YYYY-MM-DD HH:mm:ss"),
|
|
|
+ invNumber,
|
|
|
+ checkNumber
|
|
|
+ };
|
|
|
+
|
|
|
+ scanInputValue.value = "";
|
|
|
+}
|
|
|
+
|
|
|
+const handleRequeset: UploadProps["httpRequest"] = async ({ file }) => {
|
|
|
+ const _formData = new FormData();
|
|
|
+ _formData.append("img", file);
|
|
|
+ _formData.append("token", userStore.token);
|
|
|
+ const { message, code, data } = await httpImageUpload(_formData);
|
|
|
+
|
|
|
+ responseHandle({
|
|
|
+ message,
|
|
|
+ code,
|
|
|
+ handler: () => {
|
|
|
+ data.forEach(({ url, name }) => {
|
|
|
+ imgs.value.push({
|
|
|
+ inv_img: baseUrl + "/" + url,
|
|
|
+ invName: name,
|
|
|
+ invType: "2"
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const handleRemove = uploadFile => {
|
|
|
+ const delIndex = fileList.value.findIndex(
|
|
|
+ ({ uid }) => uid === uploadFile.uid
|
|
|
+ );
|
|
|
+ imgs.value.splice(delIndex, 1);
|
|
|
+ return true;
|
|
|
+};
|
|
|
+
|
|
|
+watch(
|
|
|
+ () => formItems.value,
|
|
|
+ newVal => {
|
|
|
+ const newFormData: Record<string, string> = {};
|
|
|
+ newFormData.payNo = formData.value.payNo;
|
|
|
+
|
|
|
+ newVal.forEach(item => {
|
|
|
+ if (item.prop !== "payNo") newFormData[item.prop] = "";
|
|
|
+ });
|
|
|
+
|
|
|
+ formData.value = newFormData;
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+const disabledDate = time => {
|
|
|
+ return time.getTime() > Date.now();
|
|
|
+};
|
|
|
+
|
|
|
+defineExpose({
|
|
|
+ onDisplay: () => (visible.value = true)
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <el-dialog v-model="visible" @close="handleClose">
|
|
|
+ <el-form
|
|
|
+ label-width="100px"
|
|
|
+ :model="formData"
|
|
|
+ :rules="rules"
|
|
|
+ ref="formRef"
|
|
|
+ size="small"
|
|
|
+ >
|
|
|
+ <el-form-item label="发票上传方式">
|
|
|
+ <el-select v-model="invType">
|
|
|
+ <el-option label="手工添加" value="1" />
|
|
|
+ <el-option label="ocr识别" value="2" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 扫码枪识别 -->
|
|
|
+ <el-form-item label="扫码枪" v-if="showScanInput">
|
|
|
+ <el-input
|
|
|
+ type="textarea"
|
|
|
+ placeholder="请在扫码完成后手动回车"
|
|
|
+ @keydown="handleScanKeydown"
|
|
|
+ v-model="scanInputValue"
|
|
|
+ v-bind="INPUT_MAX_LENGTH"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item
|
|
|
+ v-for="(item, index) in formItems"
|
|
|
+ :label="item.label"
|
|
|
+ :prop="item.prop"
|
|
|
+ :key="index"
|
|
|
+ >
|
|
|
+ <template v-if="item.prop === 'invoiceType'">
|
|
|
+ <el-select
|
|
|
+ v-model="formData[item.prop]"
|
|
|
+ placeholder="请选择发票类型"
|
|
|
+ w-750px
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="(type, index) in inv_type_list"
|
|
|
+ :label="type.label"
|
|
|
+ :value="type.hwy_value"
|
|
|
+ :key="index"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-else-if="item.prop === 'inv_img'">
|
|
|
+ <!-- list-type="picture" -->
|
|
|
+ <div w-full>
|
|
|
+ <el-upload
|
|
|
+ class="upload-demo"
|
|
|
+ v-model:file-list="fileList"
|
|
|
+ :before-upload="onBeforeReturnImageUpload"
|
|
|
+ :before-remove="handleRemove"
|
|
|
+ :http-request="handleRequeset"
|
|
|
+ multiple
|
|
|
+ >
|
|
|
+ <el-button type="primary">上传图片</el-button>
|
|
|
+ </el-upload>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-else-if="item.prop === 'open_time'">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="formData[item.prop]"
|
|
|
+ :disabled-date="disabledDate"
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
+ placeholder="请输入开票日期"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-else>
|
|
|
+ <el-input v-model="formData[item.prop]" v-bind="INPUT_MAX_LENGTH" />
|
|
|
+ </template>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item class="justify-end flex w-full">
|
|
|
+ <el-button type="primary" :loading="loading" @click="handleSave"
|
|
|
+ >保存</el-button
|
|
|
+ >
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </el-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.upload {
|
|
|
+ width: 178px;
|
|
|
+ height: 178px;
|
|
|
+ display: block;
|
|
|
+ border: 1px dashed var(--el-border-color);
|
|
|
+
|
|
|
+ .icon {
|
|
|
+ font-size: 24px;
|
|
|
+ color: #8c939d;
|
|
|
+ width: 178px;
|
|
|
+ height: 178px;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .text {
|
|
|
+ font-size: 20px;
|
|
|
+ line-height: 178px;
|
|
|
+ width: 178px;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ border-color: #409eff;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|