|
@@ -0,0 +1,262 @@
|
|
|
+<script setup lang="ts">
|
|
|
+import { dayjs, ElForm, ElInput, ElMessage, UploadProps } from "element-plus";
|
|
|
+import { ticketFormItems, ticketAddRules } from "../../config/configs";
|
|
|
+import { computed, ref, watch, nextTick } from "vue";
|
|
|
+import { httpAdd } from "/@/api/purchase/ticketReturn";
|
|
|
+import { useResponseHandle } from "/@/hooks";
|
|
|
+import { httpImageUpload, baseUrl } from "/@/api/other";
|
|
|
+import { useUserStore } from "/@/store/modules/user";
|
|
|
+import { inv_type_list } from "/@/utils/status";
|
|
|
+
|
|
|
+const visible = ref(false);
|
|
|
+
|
|
|
+//支持的图片格式
|
|
|
+const types = ["png", "jpg", "bmp", "jpeg"].map(format => "image/" + format);
|
|
|
+
|
|
|
+const payNo = ref("");
|
|
|
+const invType = ref("");
|
|
|
+const loading = ref(false);
|
|
|
+const formData = ref<Record<string, string>>({});
|
|
|
+const formRef = ref<InstanceType<typeof ElForm>>(null);
|
|
|
+const formItems = computed(() => ticketFormItems[invType.value] || []);
|
|
|
+const showScanInput = computed(() => invType.value === "1");
|
|
|
+const scanInputValue = ref("");
|
|
|
+const rules = ref({ ...ticketAddRules });
|
|
|
+
|
|
|
+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 handleSave() {
|
|
|
+ formRef.value.validate(async isValid => {
|
|
|
+ if (!isValid) return;
|
|
|
+ loading.value = true;
|
|
|
+
|
|
|
+ const { code, message } = await httpAdd({
|
|
|
+ payNo: payNo.value,
|
|
|
+ invType: invType.value,
|
|
|
+ ...formData.value
|
|
|
+ });
|
|
|
+
|
|
|
+ responseHandle({
|
|
|
+ code,
|
|
|
+ message,
|
|
|
+ handler: () => (visible.value = false)
|
|
|
+ });
|
|
|
+
|
|
|
+ loading.value = false;
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function handleClose() {
|
|
|
+ formData.value = {};
|
|
|
+ invType.value = "";
|
|
|
+ scanInputValue.value = "";
|
|
|
+}
|
|
|
+
|
|
|
+function handleScanKeydown(evt: KeyboardEvent) {
|
|
|
+ const { keyCode } = evt;
|
|
|
+
|
|
|
+ if (keyCode !== 13) return;
|
|
|
+
|
|
|
+ //校验扫描枪值是否含有中文逗号
|
|
|
+ if (scanInputValue.value.indexOf(",") >= 0) {
|
|
|
+ ElMessage.error("不能包含中文逗号");
|
|
|
+ return (scanInputValue.value = "");
|
|
|
+ }
|
|
|
+
|
|
|
+ const [_, ...chunks] = scanInputValue.value.split(",");
|
|
|
+ const [invoiceType, invCode, invNumber, gold, 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,
|
|
|
+ gold,
|
|
|
+ open_time: dayjs(`${year}-${month}-${day}`).format("YYYY-MM-DD HH:mm:ss"),
|
|
|
+ invNumber,
|
|
|
+ checkNumber
|
|
|
+ };
|
|
|
+ console.log(formData.value);
|
|
|
+ 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: () => {
|
|
|
+ const { url, name } = data[0];
|
|
|
+ formData.value.inv_img = baseUrl + "/" + url;
|
|
|
+ formData.value.invName = name;
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+watch(
|
|
|
+ () => formItems.value,
|
|
|
+ newVal => {
|
|
|
+ const newFormData: Record<string, string> = {};
|
|
|
+ newVal.forEach(item => (newFormData[item.prop] = ""));
|
|
|
+ formData.value = newFormData;
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+//增值税专票校验码不必填
|
|
|
+watch(
|
|
|
+ () => formData.value,
|
|
|
+ () => {
|
|
|
+ nextTick(
|
|
|
+ () =>
|
|
|
+ (rules.value.checkNumber[0].required = formData.value.invName !== "01")
|
|
|
+ );
|
|
|
+ },
|
|
|
+ {
|
|
|
+ deep: true
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+defineExpose({
|
|
|
+ onDisplay: (_payNo: string) => {
|
|
|
+ visible.value = true;
|
|
|
+ payNo.value = _payNo;
|
|
|
+ }
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <el-dialog
|
|
|
+ v-model="visible"
|
|
|
+ custom-class="ticket__dialog"
|
|
|
+ title="添加发票"
|
|
|
+ center
|
|
|
+ destroy-on-close
|
|
|
+ @close="handleClose"
|
|
|
+ >
|
|
|
+ <el-form label-width="100px" :model="formData" :rules="rules" ref="formRef">
|
|
|
+ <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"
|
|
|
+ @keydown="handleScanKeydown"
|
|
|
+ v-model="scanInputValue"
|
|
|
+ />
|
|
|
+ </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 === 'invName'">
|
|
|
+ <el-select v-model="formData[item.prop]" placeholder="请选择发票名称">
|
|
|
+ <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'">
|
|
|
+ <div>
|
|
|
+ <el-upload
|
|
|
+ class="upload"
|
|
|
+ :before-upload="onBeforeReturnImageUpload"
|
|
|
+ :http-request="handleRequeset"
|
|
|
+ :show-file-list="false"
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ class="avatar"
|
|
|
+ :src="formData[item.prop]"
|
|
|
+ v-if="formData[item.prop]"
|
|
|
+ />
|
|
|
+ <div class="text" v-else>点击上传</div>
|
|
|
+ </el-upload>
|
|
|
+ <span>大小:小于1M; 尺寸:100*100; 类型:jpg.png.bmp.jpeg</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-else-if="item.prop === 'open_time'">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="formData[item.prop]"
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
+ placeholder="请输入开票日期"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-else>
|
|
|
+ <el-input v-model="formData[item.prop]" />
|
|
|
+ </template>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item 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>
|