Quellcode durchsuchen

feat(file): 修改上传文件流

tangning vor 3 Jahren
Ursprung
Commit
75f5ce60d5

+ 8 - 11
src/api/product/index.ts

@@ -24,18 +24,15 @@ export const CameraList = (params: PageParams) =>
     },
   });
 
-export const AddAndUpload = (params: PageParams) =>
-  defHttp.post<Result>({
-    url: Api.addAndUpload,
-    params: params,
-    // data: params,
-    headers: {
-      // @ts-ignore
-        'Content-type': ContentTypeEnum.FORM_DATA,
-        // @ts-ignore
-        ignoreCancelToken: true,
+export const AddAndUpload = (params: PageParams) =>{
+  return defHttp.uploadFile<Result>(
+    {
+      url: Api.addAndUpload,
+      // onUploadProgress,
     },
-  });
+    params
+  );
+}
 
 export function uploadApi(
   params: UploadFileParams,

+ 2 - 2
src/components/Upload/src/BasicUpload.vue

@@ -11,8 +11,8 @@
             {{ fileList.length }}
           </template>
         </template>
-        <a-button @click="openPreviewModal">
-          <Icon icon="bi:eye" />
+        <a-button :disabled="fileList && !fileList.length" @click="openPreviewModal">
+          <Icon icon="bi:eye" /> 预览
           <template v-if="fileList.length && showPreviewNumber">
             {{ fileList.length }}
           </template>

+ 81 - 18
src/components/Upload/src/UploadModal.vue

@@ -9,6 +9,7 @@
     :closeFunc="handleCloseFunc"
     :maskClosable="false"
     :keyboard="false"
+    class="upload-modal"
     wrapClassName="upload-modal"
     :okButtonProps="getOkButtonProps"
     :cancelButtonProps="{ disabled: isUploadingRef }"
@@ -31,6 +32,7 @@
         :accept="getStringAccept"
         :multiple="multiple"
         :before-upload="beforeUpload"
+        :show-upload-list="false"
         class="upload-modal-toolbar__btn"
       >
         <a-button type="primary">
@@ -54,7 +56,7 @@
   import { basicProps } from './props';
   import { createTableColumns, createActionColumn } from './data';
   // utils
-  import { checkFileType, checkImgType, getBase64WithFile } from './helper';
+  import { checkImgType, getBase64WithFile } from './helper';
   import { buildUUID } from '/@/utils/uuid';
   import { isFunction } from '/@/utils/is';
   import { warn } from '/@/utils/log';
@@ -84,7 +86,7 @@
       const { t } = useI18n();
       const [register, { closeModal }] = useModalInner();
 
-      const { getAccept, getStringAccept, getHelpText } = useUploadType({
+      const { getStringAccept, getHelpText } = useUploadType({
         acceptRef: accept,
         helpTextRef: helpText,
         maxNumberRef: maxNumber,
@@ -123,19 +125,20 @@
       // 上传前校验
       function beforeUpload(file: File) {
         const { size, name } = file;
-        const { maxSize } = props;
-        const accept = unref(getAccept);
+        const { maxSize, accept } = props;
+        const type = name.split('.').pop() || '';
+        console.log('beforeUpload', type, name);
+        if (accept && accept.length > 0 && !accept.includes(type.toLowerCase())) {
+          createMessage.error(t('component.upload.accept', [accept.join(',')]));
+          return false;
+        }
+        console.log('file', type, props);
         // 设置最大值,则判断
         if (maxSize && file.size / 1024 / 1024 >= maxSize) {
           createMessage.error(t('component.upload.maxSizeMultiple', [maxSize]));
           return false;
         }
 
-        // 设置类型,则判断
-        if (accept.length > 0 && !checkFileType(file, accept)) {
-          createMessage.error!(t('component.upload.acceptUpload', [accept.join(',')]));
-          return false;
-        }
         const commonItem = {
           uuid: buildUUID(),
           file,
@@ -177,13 +180,33 @@
       //     imageList: [thumbUrl],
       //   });
       // }
-
+      /**
+       * 将中文符号转换成英文符号
+       */
+      function chineseChar2englishChar(chineseChar) {
+        // 将单引号‘’都转换成',将双引号“”都转换成"
+        var str = chineseChar.replace(/\’|\‘/g, "'").replace(/\“|\”/g, '"');
+        // 将中括号【】转换成[],将大括号{}转换成{}
+        str = str
+          .replace(/\【/g, '[')
+          .replace(/\】/g, ']')
+          .replace(/\{/g, '{')
+          .replace(/\}/g, '}');
+        // 将逗号,转换成,,将:转换成:
+        str = str.replace(/,/g, ',').replace(/:/g, ':');
+        return str;
+      }
       async function uploadApiByItem(item: FileItem) {
+        console.log('item', props, item);
         const { api, afterFetch } = props;
         if (!api || !isFunction(api)) {
           return warn('upload api must exist and be a function');
         }
         try {
+          let isZh = false;
+          if (/.*[\u4e00-\u9fa5]+.*$/.test(item.name)) {
+            isZh = true;
+          }
           item.status = UploadResultStatus.UPLOADING;
           const { data } = await props.api?.(
             {
@@ -192,7 +215,7 @@
               },
               file: item.file,
               name: props.name,
-              filename: props.filename,
+              filename: isZh ? item.uuid + '.' + item.type : props.filename,
             },
             function onUploadProgress(progressEvent: ProgressEvent) {
               const complete = ((progressEvent.loaded / progressEvent.total) * 100) | 0;
@@ -201,11 +224,11 @@
           );
           item.status = UploadResultStatus.SUCCESS;
           item.responseData = data;
-          
+
           if (afterFetch && isFunction(afterFetch)) {
             item.responseData = (await afterFetch(data)) || data;
           }
-          
+
           return {
             success: true,
             error: null,
@@ -219,10 +242,39 @@
           };
         }
       }
+      //上传文件流
+      async function uploadFileFlow(item: FileItem) {
+        console.log('item', props, item);
+        const { afterFetch } = props;
+        try {
+          let isZh = false;
+          if (/.*[\u4e00-\u9fa5]+.*$/.test(item.name)) {
+            isZh = true;
+          }
+          item.status = UploadResultStatus.UPLOADING;
 
+          item.status = UploadResultStatus.SUCCESS;
+
+          if (afterFetch && isFunction(afterFetch)) {
+            item.responseData = (await afterFetch(item)) || item;
+          }
+
+          return {
+            success: true,
+            error: null,
+          };
+        } catch (e) {
+          console.log(e);
+          item.status = UploadResultStatus.ERROR;
+          return {
+            success: false,
+            error: e,
+          };
+        }
+      }
       // 点击开始上传
       async function handleStartUpload() {
-        const { maxNumber } = props;
+        const { maxNumber,fileFlow } = props;
         if ((fileListRef.value.length + props.previewFileList?.length ?? 0) > maxNumber) {
           return createMessage.warning(t('component.upload.maxNumber', [maxNumber]));
         }
@@ -233,22 +285,27 @@
             fileListRef.value.filter((item) => item.status !== UploadResultStatus.SUCCESS) || [];
           const data = await Promise.all(
             uploadFileList.map((item) => {
+              if(fileFlow){
+                return uploadFileFlow(item);
+              }else{
               return uploadApiByItem(item);
+              }
             }),
           );
           isUploadingRef.value = false;
           // 生产环境:抛出错误
           const errorList = data.filter((item: any) => !item.success);
           if (errorList.length > 0) throw errorList;
-        } catch (e) {
+        } catch (error) {
+          console.log(error);
           isUploadingRef.value = false;
-          throw e;
+          throw error;
         }
       }
 
       //   点击保存
       function handleOk() {
-        const { maxNumber } = props;
+        const { maxNumber,fileFlow  } = props;
 
         if (fileListRef.value.length > maxNumber) {
           return createMessage.warning(t('component.upload.maxNumber', [maxNumber]));
@@ -260,8 +317,13 @@
 
         for (const item of fileListRef.value) {
           const { status, responseData } = item;
+          console.log('responseData', item);
           if (status === UploadResultStatus.SUCCESS && responseData) {
-            fileList.push(responseData.url);
+            if(fileFlow){
+              fileList.push(responseData.name);
+            }else{
+              fileList.push(responseData.url);
+            }
           }
         }
         // 存在一个上传成功的即可保存
@@ -302,6 +364,7 @@
         handleCloseFunc,
         getIsSelectFile,
         getUploadBtnText,
+        chineseChar2englishChar,
         t,
       };
     },

+ 1 - 1
src/components/Upload/src/UploadPreviewModal.vue

@@ -2,7 +2,7 @@
   <BasicModal
     width="800px"
     :title="t('component.upload.preview')"
-    wrapClassName="upload-preview-modal"
+    class="upload-preview-modal"
     v-bind="$attrs"
     @register="register"
     :showOkBtn="false"

+ 1 - 1
src/components/Upload/src/data.tsx

@@ -40,7 +40,7 @@ export function createTableColumns(): BasicColumn[] {
         return (
           <span>
             <p class="truncate mb-1" title={text}>
-              {text}
+              {text && text.length < 30 ? text : text.slice(0, 30) + '...'}
             </p>
             <Progress percent={percent} size="small" status={status} />
           </span>

+ 3 - 1
src/components/Upload/src/helper.ts

@@ -11,7 +11,9 @@ export function checkImgType(file: File) {
 }
 
 export function isImgTypeByName(name: string) {
-  return /\.(jpg|jpeg|png|gif)$/i.test(name);
+  // return /\.(jpg|jpeg|png|gif)$/i.test(name);
+  // return /\.(jpg|jpeg|png|gif)$/i.test(name.split('?').shift());
+  return /\.(jpg|jpeg|png|gif)$/i.test(name.split('?').shift());
 }
 
 export function getBase64WithFile(file: File) {

+ 5 - 0
src/components/Upload/src/props.ts

@@ -25,6 +25,11 @@ export const basicProps = {
     type: Boolean as PropType<boolean>,
     default: true,
   },
+  // 上传文件流
+  fileFlow: {
+    type: Boolean as PropType<boolean>,
+    default: false,
+  },
   uploadParams: {
     type: Object as PropType<any>,
     default: {},

+ 15 - 5
src/views/product/AddModal.vue

@@ -17,7 +17,7 @@
   </BasicModal>
 </template>
 <script lang="ts">
-  import { defineComponent, ref, nextTick, onMounted } from 'vue';
+  import { defineComponent, ref, nextTick, onMounted, reactive } from 'vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
   import { useMessage } from '/@/hooks/web/useMessage';
@@ -33,6 +33,9 @@
     emits: ['update', 'register'],
     setup(props, { emit }) {
       const modelRef = ref({});
+      const fileFlow = reactive({
+        file:null
+      })
       const { createMessage } = useMessage();
       const schemas: FormSchema[] = [
         {
@@ -127,10 +130,12 @@
             api: uploadApi,
             maxNumber: 1,
             maxSize: 1000,
+            fileFlow:true,
             accept: ['4dage'],
             afterFetch: function (data) {
-              Reflect.set(data, 'url', data.data);
               console.log('uploadApi',data)
+              Reflect.set(data, 'url', data.file);
+              fileFlow.file = data.file
               return data;
             },
           },
@@ -221,11 +226,15 @@
       const handleSubmit = async () => {
         try {
           const params = await validate();
-          console.log('res', params);
-          const res = await AddAndUpload({
+          const apiData = {
+            data:{
             ...params as any,
             type:modelRef.value,
-          });
+            file:fileFlow.file,
+            }
+          }
+          console.log('res', apiData);
+          const res = await AddAndUpload(apiData);
           console.log('res', res);
           closeModal();
           resetFields();
@@ -245,6 +254,7 @@
         schemas,
         registerForm,
         model: modelRef,
+        fileFlow,
         handleVisibleChange,
         handleSubmit,
         addListFunc,

+ 10 - 9
src/views/productOperation/sceneManager/laserScene.vue

@@ -3,8 +3,7 @@
     <template #toolbar>
       <!-- <a-button type="primary" @click="exportExcel"> 导出1</a-button> -->
     </template>
-    <template #bodyCell="{ column, record }">
-      <template v-if="column.dataIndex === 'action'">
+    <template #action="{ column, record }">
         <TableAction
           stopButtonPropagation
           :actions="[
@@ -24,7 +23,6 @@
             },
           ]"
         />
-      </template>
     </template>
   </BasicTable>
 </template>
@@ -160,11 +158,14 @@
           dataIndex: 'statusString',
           width: 80,
         },
-        // {
-        //   title: '操作',
-        //   dataIndex: 'action',
-        //   width: 80,
-        // },
+        {
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+          ifShow:true,
+          fixed: 'right',
+          width: 80,
+        },
       ];
       const searchForm: Partial<FormProps> = {
         labelWidth: 100,
@@ -221,7 +222,7 @@
         useSearchForm: true,
         formConfig: searchForm,
         showTableSetting: true,
-        rowKey: 'id',
+        rowKey: 'num',
         fetchSetting: {
           pageField: 'pageNum',
           sizeField: 'pageSize',