Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(upload): add allowUploadDuplicateFile props #636

Merged
merged 3 commits into from
Mar 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions examples/upload/demos/file-flow-list-duplicate.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<template>
<div class="t-upload__file-flow-demo">
<div>是否重复文件上传:<t-switch v-model="allowUploadDuplicateFile"></t-switch></div>
<t-upload
v-model="files"
action="https://service-bv448zsw-1257786608.gz.apigw.tencentcs.com/api/upload-demo"
placeholder="支持批量上传文件,文件格式不限,最多只能上传 10 份文件"
theme="file-flow"
multiple
:allowUploadDuplicateFile="allowUploadDuplicateFile"
:auto-upload="false"
:max="10"
></t-upload>
</div>
</template>

<script>
export default {
name: 'TUploadFileFlow',

data() {
return {
files: [],
allowUploadDuplicateFile: false,
};
},
};
</script>
3 changes: 2 additions & 1 deletion examples/upload/upload.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
-- | -- | -- | -- | --
accept | String | - | 接受上传的文件类型,[查看 W3C示例](https://www.w3schools.com/tags/att_input_accept.asp),[查看 MDN 示例](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/Input/file) | N
action | String | - | 上传接口 | N
allowUploadDuplicateFile | Boolean | false | 是否允许重复上传相同文件名的文件 | N
autoUpload | Boolean | true | 是否选取文件后自动上传 | N
beforeUpload | Function | - | 上传文件之前的钩子,参数为上传的文件,返回值决定是否上传。TS 类型:`(file: File | UploadFile) => boolean | Promise<boolean>` | N
data | Object | - | 上传文件时所需的额外数据。TS 类型:`Record<string, any> | ((file: File) => Record<string, any>)` | N
Expand All @@ -26,7 +27,7 @@ formatResponse | Function | - | 用于格式化文件上传后的响应数据。
headers | Object | - | 设置上传的请求头部。TS 类型:`{[key: string]: string}` | N
isBatchUpload | Boolean | false | 文件是否作为一个独立文件包,整体替换,整体删除。不允许追加文件,只允许替换文件 | N
max | Number | 0 | 用于控制文件上传数量,值为 0 则不限制 | N
method | String | POST | HTTP 请求类型。可选项:POST/GET/PUT/OPTION | N
method | String | POST | HTTP 请求类型。可选项:POST/GET/PUT/OPTION/PATCH/post/get/put/option/patch | N
multiple | Boolean | false | 是否支持多选文件 | N
name | String | 'file' | 文件上传时的名称 | N
placeholder | String | - | 占位符 | N
Expand Down
2 changes: 1 addition & 1 deletion src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export type TNode<T = undefined> = T extends undefined
export type JsxNode = TNodeReturnValue;

export type AttachNodeReturnValue = HTMLElement | Element | Document;
export type AttachNode = CSSSelector | (() => AttachNodeReturnValue);
export type AttachNode = CSSSelector | ((triggerNode?: HTMLElement) => AttachNodeReturnValue);

// 与滚动相关的容器类型,因为 document 上没有 scroll 相关属性, 因此排除document
export type ScrollContainerElement = Window | HTMLElement;
Expand Down
11 changes: 9 additions & 2 deletions src/upload/flow-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export default Vue.extend({

props: {
showUploadProgress: props.showUploadProgress,
// 是否过滤重复文件
allowUploadDuplicateFile: props.allowUploadDuplicateFile,
// 已上传完成的文件
files: Array as PropType<Array<UploadFile>>,
// 合并上传
Expand Down Expand Up @@ -65,8 +67,13 @@ export default Vue.extend({
waitingUploadFiles(): Array<UploadFile> {
const list: Array<UploadFile> = [];
this.toUploadFiles.forEach((item) => {
const r = this.files.filter((t) => t.name === item.name);
if (!r.length) {
// 判断是否需要过滤重复文件
if (!this.allowUploadDuplicateFile) {
const r = this.files.filter((t) => t.name === item.name);
if (!r.length) {
list.push(item);
}
} else {
list.push(item);
}
});
Expand Down
4 changes: 3 additions & 1 deletion src/upload/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export default {
type: String,
default: '',
},
/** 是否允许重复上传相同文件名的文件 */
allowUploadDuplicateFile: Boolean,
/** 是否选取文件后自动上传 */
autoUpload: {
type: Boolean,
Expand Down Expand Up @@ -76,7 +78,7 @@ export default {
default: 'POST' as TdUploadProps['method'],
validator(val: TdUploadProps['method']): boolean {
if (!val) return true;
return ['POST', 'GET', 'PUT', 'OPTION'].includes(val);
return ['POST', 'GET', 'PUT', 'OPTION', 'PATCH', 'post', 'get', 'put', 'option', 'patch'].includes(val);
},
},
/** 是否支持多选文件 */
Expand Down
7 changes: 6 additions & 1 deletion src/upload/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export interface TdUploadProps {
* @default ''
*/
action?: string;
/**
* 是否允许重复上传相同文件名的文件
* @default false
*/
allowUploadDuplicateFile?: boolean;
/**
* 是否选取文件后自动上传
* @default true
Expand Down Expand Up @@ -82,7 +87,7 @@ export interface TdUploadProps {
* HTTP 请求类型
* @default POST
*/
method?: 'POST' | 'GET' | 'PUT' | 'OPTION';
method?: 'POST' | 'GET' | 'PUT' | 'OPTION' | 'PATCH' | 'post' | 'get' | 'put' | 'option' | 'patch';
/**
* 是否支持多选文件
* @default false
Expand Down
6 changes: 5 additions & 1 deletion src/upload/upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { renderContent } from '../utils/render-tnode';
import props from './props';
import { ClassName } from '../common';
import { emitEvent } from '../utils/event';
import { dedupeFile } from './util';
import {
HTMLInputEvent,
SuccessContext,
Expand Down Expand Up @@ -285,7 +286,9 @@ export default mixins(getConfigReceiverMixins<Vue, UploadConfig>('upload')).exte
if (!canUpload) return;
const newFiles = this.toUploadFiles.concat();
newFiles.push(uploadFile);
this.toUploadFiles = [...new Set(newFiles)];
this.toUploadFiles = !this.allowUploadDuplicateFile
? dedupeFile([...new Set(newFiles)])
: [...new Set(newFiles)];
this.loadingFile = uploadFile;
if (this.autoUpload) {
this.upload(uploadFile);
Expand Down Expand Up @@ -688,6 +691,7 @@ export default mixins(getConfigReceiverMixins<Vue, UploadConfig>('upload')).exte
toUploadFiles={this.toUploadFiles}
remove={this.handleListRemove}
showUploadProgress={this.showUploadProgress}
allowUploadDuplicateFile={this.allowUploadDuplicateFile}
upload={this.multipleUpload}
cancel={this.cancelUpload}
display={this.theme}
Expand Down
15 changes: 13 additions & 2 deletions src/upload/util.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import uniqWith from 'lodash/uniqWith';
import { prefix } from '../config';
import { UploadFile } from './type';

export const UPLOAD_NAME = `${prefix}-upload`;

Expand Down Expand Up @@ -35,10 +37,19 @@ export function abridgeName(inputName: string, leftCount = 5, rightcount = 7): s
const w = name[i];
const isCn = escape(w).indexOf('%u') === 0;
if (i < leftCount * 2 && leftLength < leftCount) {
isCn ? leftLength += 1 : (leftLength += 2);
isCn ? (leftLength += 1) : (leftLength += 2);
} else if (i > i - rightcount && rightLength < rightcount) {
isCn ? rightLength += 1 : (rightLength += 2);
isCn ? (rightLength += 1) : (rightLength += 2);
}
}
return name.replace(new RegExp(`^(.{${leftLength}})(.+)(.{${rightLength}})$`), '$1…$3');
}
/**
* 重复数组检查
* @param files Array
* @param key string default name
* @returns Array of files
*/
export function dedupeFile(files: Array<UploadFile>, key = 'name'): any {
return uniqWith(files, (val1, val2) => val1[key] === val2[key]);
}
30 changes: 30 additions & 0 deletions test/ssr/__snapshots__/ssr.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -16260,6 +16260,36 @@ exports[`ssr snapshot test renders ./examples/upload/demos/file-flow-list-batch-
</div>
`;

exports[`ssr snapshot test renders ./examples/upload/demos/file-flow-list-duplicate.vue correctly 1`] = `
<div class="t-upload__file-flow-demo">
<div>是否重复文件上传:<div class="t-switch t-size-m"><span class="t-switch__handle"></span>
<div class="t-switch__content t-size-m"></div>
</div>
</div>
<div class="t-upload"><input type="file" multiple="multiple" accept="" hidden="hidden">
<div class="t-upload__flow t-upload__flow-file-flow">
<div class="t-upload__flow-op">
<div class="t-upload__trigger"><button type="button" class="t-button t-size-m t-button--variant-outline t-button--theme-default"><span class="t-button__text">选择文件</span></button></div><small class="t-size-s t-upload__flow-placeholder">支持批量上传文件,文件格式不限,最多只能上传 10 份文件</small>
</div>
<table class="t-upload__flow-table">
<tr>
<th>文件名</th>
<th>大小</th>
<th>状态</th>
<th>操作</th>
</tr>
<tr>
<td colspan="4">
<div class="t-upload__flow-empty">点击上方“选择文件”或将文件拖拽到此区域</div>
</td>
</tr>
</table>
<div class="t-upload__flow-bottom"><button type="button" class="t-button t-size-m t-button--variant-base t-button--theme-default"><span class="t-button__text">取消</span></button><button type="button" disabled="disabled" class="t-button t-size-m t-button--variant-base t-button--theme-primary t-is-disabled"><span class="t-button__text">开始上传</span></button></div>
</div>
</div>
</div>
`;

exports[`ssr snapshot test renders ./examples/upload/demos/image.vue correctly 1`] = `
<div class="tdesign-demo-upload">
<div class="tdesign-demo-upload-item">
Expand Down
112 changes: 112 additions & 0 deletions test/unit/upload/__snapshots__/demo.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,118 @@ exports[`Upload base fileFlowListBatchUpload works fine 1`] = `
</div>
`;

exports[`Upload base fileFlowListDuplicate works fine 1`] = `
<div
class="t-upload__file-flow-demo"
>
<div>
是否重复文件上传:
<div
class="t-switch t-size-m"
>
<span
class="t-switch__handle"
/>
<div
class="t-switch__content t-size-m"
/>
</div>
</div>

<div
class="t-upload"
>
<input
accept=""
hidden="hidden"
multiple="multiple"
type="file"
/>
<div
class="t-upload__flow t-upload__flow-file-flow"
>
<div
class="t-upload__flow-op"
>
<div
class="t-upload__trigger"
>
<button
class="t-button t-size-m t-button--variant-outline t-button--theme-default"
type="button"
>
<span
class="t-button__text"
>
选择文件
</span>
</button>
</div>
<small
class="t-size-s t-upload__flow-placeholder"
>
支持批量上传文件,文件格式不限,最多只能上传 10 份文件
</small>
</div>
<table
class="t-upload__flow-table"
>
<tr>
<th>
文件名
</th>
<th>
大小
</th>
<th>
状态
</th>
<th>
操作
</th>
</tr>
<tr>
<td
colspan="4"
>
<div
class="t-upload__flow-empty"
>
点击上方“选择文件”或将文件拖拽到此区域
</div>
</td>
</tr>
</table>
<div
class="t-upload__flow-bottom"
>
<button
class="t-button t-size-m t-button--variant-base t-button--theme-default"
type="button"
>
<span
class="t-button__text"
>
取消
</span>
</button>
<button
class="t-button t-size-m t-button--variant-base t-button--theme-primary t-is-disabled"
disabled="disabled"
type="button"
>
<span
class="t-button__text"
>
开始上传
</span>
</button>
</div>
</div>
</div>
</div>
`;

exports[`Upload base image works fine 1`] = `
<div
class="tdesign-demo-upload"
Expand Down
5 changes: 5 additions & 0 deletions test/unit/upload/demo.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import requestMethod from '@/examples/upload/demos/request-method.vue';
import singleCustom from '@/examples/upload/demos/single-custom.vue';
import singleInput from '@/examples/upload/demos/single-input.vue';
import table from '@/examples/upload/demos/table.vue';
import fileFlowListDuplicate from '@/examples/upload/demos/file-flow-list-duplicate.vue';

// unit test for component in examples.
describe('Upload', () => {
Expand Down Expand Up @@ -66,4 +67,8 @@ describe('Upload', () => {
const wrapper = mount(table);
expect(wrapper.element).toMatchSnapshot();
});
it('base fileFlowListDuplicate works fine', () => {
const wrapper = mount(fileFlowListDuplicate);
expect(wrapper.element).toMatchSnapshot();
});
});