ny
22 小时以前 282fbc6488f4e8ceb5fda759f963ee88fbf7b999
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
<script lang="ts" setup>
import type { UploadChangeParam, UploadFile } from 'ant-design-vue';
 
import { computed, reactive, toRefs } from 'vue';
 
import { useGlobSetting, useMessage } from '@jnpf/hooks';
import { BasicModal, useModalInner } from '@jnpf/ui/modal';
import { downloadByUrl } from '@jnpf/utils';
 
import { useAccessStore } from '@vben/stores';
 
import { Upload as AUpload } from 'ant-design-vue';
 
import { importData, templateDownload } from '#/api/system/baseLang';
import { $t } from '#/locales';
 
interface State {
  fileName: string;
  fileList: UploadFile[];
  btnLoading: boolean;
}
 
const emit = defineEmits(['register', 'reload']);
const state = reactive<State>({
  fileName: '',
  fileList: [],
  btnLoading: false,
});
const { fileName, fileList, btnLoading } = toRefs(state);
const [registerModal, { closeModal }] = useModalInner(init);
const { createMessage, createConfirm } = useMessage();
const globSetting = useGlobSetting();
const accessStore = useAccessStore();
 
const getAction = computed(() => `${globSetting.apiURL}/api/system/BaseLang/Uploader`);
const getHeaders = computed(() => ({ Authorization: accessStore.accessToken as string }));
 
function init() {
  state.fileName = '';
  state.fileList = [];
  state.btnLoading = false;
}
function handleImport() {
  if (!state.fileList.length || !state.fileName) return createMessage.warning('请先上传文件');
  state.btnLoading = true;
  importData({ fileName: state.fileName })
    .then((res) => {
      state.btnLoading = false;
      createMessage.success(res.msg);
      emit('reload');
      closeModal();
    })
    .catch(() => {
      state.btnLoading = false;
    });
}
function handleFileChange({ file }: UploadChangeParam) {
  if (file.status === 'error') {
    createMessage.error('上传失败');
    return;
  }
  if (file.status === 'done') {
    if (file.response.code === 200) {
      state.fileName = file.response.data.name;
    } else {
      createMessage.error(file.response.msg);
    }
  }
}
function beforeUpload(file) {
  const fileType = file.name.replace(/.+\./, '');
  const isAccept = ['xls', 'xlsx'].includes(fileType.toLowerCase());
  if (!isAccept) {
    createMessage.error('文件格式不正确');
    return AUpload.LIST_IGNORE;
  }
  const isRightSize = file.size / 1024 < 500;
  if (!isRightSize) {
    createMessage.error('文件大小超过500KB');
    return AUpload.LIST_IGNORE;
  }
  return true;
}
function handleFileRemove(file) {
  return new Promise<void>((resolve, reject) => {
    createConfirm({
      iconType: 'warning',
      title: $t('common.tipTitle'),
      content: `确定移除${file.name}?`,
      onOk: () => {
        state.fileName = '';
        resolve();
      },
      onCancel: () => {
        reject(new Error('移除失败'));
      },
    });
  });
}
function handleTemplateDownload() {
  templateDownload().then((res) => {
    downloadByUrl({ url: res.data?.url });
  });
}
</script>
<template>
  <BasicModal
    v-bind="$attrs"
    @register="registerModal"
    title="批量导入"
    :width="1000"
    :show-cancel-btn="false"
    :show-ok-btn="false"
    destroy-on-close
    class="jnpf-import-modal">
    <div class="import-main">
      <div class="upload">
        <div class="up_left">
          <img src="@/assets/images/upload.png" />
        </div>
        <div class="up_right !pt-[16px]">
          <p class="title">上传填好的翻译文档</p>
          <p class="tip !my-[10px]">文件后缀名必须是xls或xlsx,文件大小不超过500KB,最多支持导入1000条数据</p>
          <p class="tip !my-[10px]">若文档中的翻译标记已存在库中则直接更新</p>
          <AUpload
            v-model:file-list="fileList"
            class="upload-area"
            accept=".xls,.xlsx"
            :max-count="1"
            :action="getAction"
            :headers="getHeaders"
            :before-upload="beforeUpload"
            @remove="handleFileRemove"
            @change="handleFileChange">
            <a-button type="link">上传文件</a-button>
          </AUpload>
        </div>
      </div>
      <div class="upload">
        <div class="up_left">
          <img src="@/assets/images/import.png" />
        </div>
        <div class="up_right">
          <p class="title">填写翻译文档</p>
          <p class="tip">请按照数据模板的格式准备导入数据,模板中的表头名称不可更改,表头行不能删除</p>
          <a-button type="link" @click="handleTemplateDownload()">下载模板</a-button>
        </div>
      </div>
    </div>
    <template #insertFooter>
      <a-button @click="closeModal()">{{ $t('common.cancelText') }}</a-button>
      <a-button type="primary" @click="handleImport" :loading="btnLoading" :disabled="!fileName">上传</a-button>
    </template>
  </BasicModal>
</template>