| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- <template>
- <!-- 新增发票对话框 -->
- <el-dialog v-model="dialog.visible" :title="dialog.title" width="800px" :before-close="handleClose">
- <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
- <!-- 发票信息 -->
- <el-divider content-position="left">
- <span style="color: #409eff; font-weight: 600">发票信息</span>
- </el-divider>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="发票类型" prop="invoiceType">
- <el-select v-model="form.invoiceType" placeholder="请选择发票类型" clearable style="width: 100%">
- <el-option v-for="dict in invoice_type" :key="dict.value" :label="dict.label" :value="dict.value" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="发票代码" prop="invoiceCode">
- <el-input v-model="form.invoiceCode" placeholder="请填写发票代码" clearable />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="开票公司名称" prop="invoiceCompanyName">
- <el-input v-model="form.invoiceCompanyName" placeholder="请填写开票公司名称" clearable />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="发票金额" prop="invoiceAmount">
- <el-input-number v-model="form.invoiceAmount" :controls="false" clearable style="width: 100%"> </el-input-number>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="开票日期" prop="invoiceDate">
- <el-date-picker v-model="form.invoiceDate" type="date" placeholder="请选择开票日期" style="width: 100%" value-format="YYYY-MM-DD" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="备注" prop="remark">
- <el-input v-model="form.remark" type="textarea" :min="2" placeholder="请填写备注" clearable />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item label="发票附件" prop="invoiceAnnex">
- <el-upload
- :action="uploadAction"
- :on-success="handleUploadSuccess"
- :before-upload="beforeUpload"
- :on-remove="handleRemoveUploadFile"
- :on-preview="handlePreviewUploadFile"
- :file-list="fileList"
- multiple
- >
- <el-button type="primary" icon="Upload">点击上传</el-button>
- <template #tip>
- <div class="el-upload__tip">支持jpg/png/xlsx等文件,单个文件不超过50MB</div>
- </template>
- </el-upload>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="handleClose">取消</el-button>
- <el-button type="primary" :loading="buttonLoading" @click="handleSubmit">提交</el-button>
- </div>
- </template>
- </el-dialog>
- </template>
- <script setup name="AddInvoiceDialog" lang="ts">
- const { proxy } = getCurrentInstance() as ComponentInternalInstance;
- const { invoice_type } = toRefs<any>(proxy?.useDict('invoice_type'));
- interface InvoiceForm {
- invoiceType?: string;
- invoiceCode?: string;
- invoiceCompanyName?: string;
- invoiceAmount?: number;
- invoiceDate?: string;
- remark?: string;
- invoiceAnnex?: string;
- }
- const initFormData: InvoiceForm = {
- invoiceType: undefined,
- invoiceCode: undefined,
- invoiceCompanyName: undefined,
- invoiceAmount: undefined,
- remark: undefined,
- invoiceDate: undefined,
- invoiceAnnex: undefined
- };
- const formRef = ref<ElFormInstance>();
- const buttonLoading = ref(false);
- const form = ref<InvoiceForm>({ ...initFormData });
- const fileList = ref<any[]>([]);
- const uploadAction = import.meta.env.VITE_APP_BASE_API + '/resource/oss/upload';
- const dialog = reactive<DialogOption>({
- visible: false,
- title: '发票信息'
- });
- const rules = reactive({
- invoiceType: [{ required: true, message: '请选择发票类型', trigger: 'change' }],
- invoiceCode: [{ required: true, message: '请填写发票代码', trigger: 'blur' }],
- invoiceCompanyName: [{ required: true, message: '请填写开票公司名称', trigger: 'blur' }],
- invoiceAmount: [
- { required: true, message: '请填写发票金额', trigger: 'blur' },
- {
- pattern: /^(0|[1-9]\d*)(\.\d{1,2})?$/ as RegExp,
- message: '请输入正确的金额格式,最多保留两位小数',
- trigger: 'blur'
- }
- ]
- // invoiceDate: [{ required: true, message: '请选择开票日期', trigger: 'change' }]
- } as any);
- /** 打开对话框 */
- const open = (data?: InvoiceForm) => {
- reset();
- if (data) {
- // 编辑模式
- Object.assign(form.value, data);
- // 解析附件地址并回显附件列表
- if (data.invoiceAnnex) {
- const urls = data.invoiceAnnex.split(',').filter((url) => url.trim());
- fileList.value = urls.map((url, index) => {
- const fileName = url.split('/').pop() || `附件${index + 1}`;
- return {
- name: fileName,
- url: url.trim(),
- uid: Date.now() + index,
- status: 'success'
- };
- });
- }
- }
- dialog.visible = true;
- };
- /** 重置表单 */
- const reset = () => {
- form.value = { ...initFormData };
- fileList.value = [];
- formRef.value?.clearValidate();
- };
- /** 上传前校验 */
- const beforeUpload = (file: any) => {
- const isLt50M = file.size / 1024 / 1024 < 50;
- if (!isLt50M) {
- proxy?.$modal.msgWarning('上传文件大小不能超过 50MB!');
- }
- return isLt50M;
- };
- /** 上传成功回调 */
- function handleUploadSuccess(response: any, file: any, fileListParam: any[]) {
- if (response.code === 200) {
- // 更新 fileList
- fileList.value = fileListParam;
- // 收集所有已上传成功的文件URL
- const urls = fileListParam
- .filter((f: any) => f.response?.code === 200 || f.url)
- .map((f: any) => f.response?.data?.url || f.url)
- .filter(Boolean);
- form.value.invoiceAnnex = urls.join(',');
- proxy?.$modal.msgSuccess('文件上传成功');
- } else {
- proxy?.$modal.msgError(response.msg || '文件上传失败');
- }
- }
- /** 删除文件 */
- const handleRemoveUploadFile = (uploadFile: any) => {
- form.value.invoiceAnnex = fileList.value
- .map((f) => f.url)
- .filter(Boolean)
- .join(',');
- };
- /** 预览文件 */
- const handlePreviewUploadFile = (uploadFile: any) => {
- if (uploadFile.url) {
- window.open(uploadFile.url, '_blank');
- } else {
- proxy?.$modal.msgWarning('文件地址不存在');
- }
- };
- /** 提交表单 */
- const handleSubmit = async () => {
- if (!formRef.value) return;
- await formRef.value.validate(async (valid) => {
- if (valid) {
- buttonLoading.value = true;
- try {
- // 返回发票数据给父组件
- emit('success', form.value);
- dialog.visible = false;
- proxy?.$modal.msgSuccess('添加成功');
- } catch (error) {
- console.error(error);
- } finally {
- buttonLoading.value = false;
- }
- }
- });
- };
- /** 关闭对话框 */
- const handleClose = () => {
- if (buttonLoading.value) {
- return;
- }
- dialog.visible = false;
- reset();
- };
- const emit = defineEmits(['success']);
- defineExpose({
- open
- });
- </script>
- <style scoped lang="scss">
- .dialog-footer {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
- }
- </style>
|