初始化项目, 添加TDesign等包

This commit is contained in:
zhengw
2025-11-28 16:49:36 +08:00
commit 3e53beb7bb
980 changed files with 39201 additions and 0 deletions

View File

@@ -0,0 +1,238 @@
var classPrefix = '';
var startIndex = 0;
var endIndex = 0;
var dragCollisionList = [];
var isOutRange = function (x1, y1, x2, y2, x3, y3) {
return x1 < 0 || x1 >= y1 || x2 < 0 || x2 >= y2 || x3 < 0 || x3 >= y3;
};
var sortCore = function (sKey, eKey, st) {
var _ = st.dragBaseData;
var excludeFix = function (cKey, type) {
if (st.list[cKey].fixed) {
// fixed 元素位置不会变化, 这里直接用 cKey(sortKey) 获取, 更加快捷
type ? --cKey : ++cKey;
return excludeFix(cKey, type);
}
return cKey;
};
// 先获取到 endKey 对应的 realKey, 防止下面排序过程中该 realKey 被修改
var endRealKey = -1;
st.list.forEach(function (item) {
if (item.sortKey === eKey) endRealKey = item.realKey;
});
return st.list.map(function (item) {
if (item.fixed) return item;
var cKey = item.sortKey;
var rKey = item.realKey;
if (sKey < eKey) {
// 正序拖动
if (cKey > sKey && cKey <= eKey) {
--rKey;
cKey = excludeFix(--cKey, true);
} else if (cKey === sKey) {
rKey = endRealKey;
cKey = eKey;
}
} else if (sKey > eKey) {
// 倒序拖动
if (cKey >= eKey && cKey < sKey) {
++rKey;
cKey = excludeFix(++cKey, false);
} else if (cKey === sKey) {
rKey = endRealKey;
cKey = eKey;
}
}
if (item.sortKey !== cKey) {
item.tranX = (cKey % _.columns) * 100 + '%';
item.tranY = Math.floor(cKey / _.columns) * 100 + '%';
item.sortKey = cKey;
item.realKey = rKey;
}
return item;
});
};
var triggerCustomEvent = function (list, type, ins) {
var _list = [],
listData = [];
list.forEach(function (item) {
_list[item.sortKey] = item;
});
_list.forEach(function (item) {
if (!item.extraNode) {
listData.push(item.data);
}
});
ins.triggerEvent(type, { listData: listData });
};
var longPress = function (event, ownerInstance) {
var ins = event.instance;
var st = ownerInstance.getState();
var _ = st.dragBaseData;
var sTouch = event.changedTouches[0];
if (!sTouch) return;
st.cur = ins.getDataset().index;
longPressIndex = st.cur;
// 初始项是固定项则返回
var item = st.list[st.cur];
if (item && item.fixed) return;
// 如果已经在 drag 中则返回, 防止多指触发 drag 动作, touchstart 事件中有效果
if (st.dragging) return;
st.dragging = true;
ownerInstance.callMethod('dragStatusChange', { dragging: true });
// 计算X,Y轴初始位移, 使 item 中心移动到点击处, 单列时候X轴初始不做位移
st.tranX = _.columns === 1 ? 0 : sTouch.pageX - (_.itemWidth / 2 + _.wrapLeft);
st.tranY = sTouch.pageY - (_.itemHeight / 2 + _.wrapTop);
st.sId = sTouch.identifier;
ins.setStyle({
transform: 'translate3d(' + st.tranX + 'px, ' + st.tranY + 'px, 0)',
});
st.itemsInstance.forEach(function (item, index) {
item.removeClass(classPrefix + '__drag--tran').removeClass(classPrefix + '__drag--cur');
item.addClass(index === st.cur ? classPrefix + '__drag--cur' : classPrefix + '__drag--tran');
});
ownerInstance.callMethod('dragVibrate', { vibrateType: 'longPress' });
};
var touchMove = function (event, ownerInstance) {
var ins = event.instance;
var st = ownerInstance.getState();
var _ = st.dragBaseData;
var mTouch = event.changedTouches[0];
if (!mTouch) return;
if (!st.dragging) return;
// 如果不是同一个触发点则返回
if (st.sId !== mTouch.identifier) return;
// 计算X,Y轴位移, 单列时候X轴初始不做位移
var tranX = _.columns === 1 ? 0 : mTouch.pageX - (_.itemWidth / 2 + _.wrapLeft);
var tranY = mTouch.pageY - (_.itemHeight / 2 + _.wrapTop);
// 到顶到底自动滑动
if (mTouch.clientY > _.windowHeight - _.itemHeight - _.realBottomSize) {
// 当前触摸点pageY + item高度 - (屏幕高度 - 底部固定区域高度)
ownerInstance.callMethod('pageScroll', {
scrollTop: mTouch.pageY + _.itemHeight - (_.windowHeight - _.realBottomSize),
});
} else if (mTouch.clientY < _.itemHeight + _.realTopSize) {
// 当前触摸点pageY - item高度 - 顶部固定区域高度
ownerInstance.callMethod('pageScroll', {
scrollTop: mTouch.pageY - _.itemHeight - _.realTopSize,
});
}
// 设置当前激活元素偏移量
ins.setStyle({
transform: 'translate3d(' + tranX + 'px, ' + tranY + 'px, 0)',
});
var startKey = st.list[st.cur].sortKey;
var curX = Math.round(tranX / _.itemWidth);
var curY = Math.round(tranY / _.itemHeight);
var endKey = curX + _.columns * curY;
// 目标项是固定项则返回
var item = st.list[endKey];
if (item && item.fixed) return;
// X轴或Y轴超出范围则返回
if (isOutRange(curX, _.columns, curY, _.rows, endKey, st.list.length)) return;
// 防止拖拽过程中发生乱序问题
if (startKey === endKey || startKey === st.preStartKey) return;
st.preStartKey = startKey;
dragCollisionList = sortCore(startKey, endKey, st);
startIndex = startKey;
endIndex = endKey;
st.itemsInstance.forEach(function (itemIns, index) {
var item = dragCollisionList[index];
if (index !== st.cur) {
itemIns.setStyle({
transform: 'translate3d(' + item.tranX + ',' + item.tranY + ', 0)',
});
}
});
ownerInstance.callMethod('dragVibrate', { vibrateType: 'touchMove' });
ownerInstance.callMethod('dragCollision', {
dragCollisionList: dragCollisionList,
startIndex: startIndex,
endIndex: endIndex,
});
triggerCustomEvent(dragCollisionList, 'change', ownerInstance);
};
var touchEnd = function (event, ownerInstance) {
var ins = event.instance;
var st = ownerInstance.getState();
if (!st.dragging) return;
triggerCustomEvent(st.list, 'sortend', ownerInstance);
ins.addClass(classPrefix + '__drag--tran');
ins.setStyle({
transform: 'translate3d(' + st.list[st.cur].tranX + ',' + st.list[st.cur].tranY + ', 0)',
});
st.preStartKey = -1;
st.dragging = false;
ownerInstance.callMethod('dragStatusChange', { dragging: false });
ownerInstance.callMethod('dragEnd', {
dragCollisionList: dragCollisionList,
startIndex: startIndex,
endIndex: endIndex,
});
st.cur = -1;
st.tranX = 0;
st.tranY = 0;
};
var baseDataObserver = function (newVal, oldVal, ownerInstance, ins) {
var st = ownerInstance.getState();
st.dragBaseData = newVal;
classPrefix = newVal.classPrefix;
};
var listObserver = function (newVal, oldVal, ownerInstance, ins) {
var st = ownerInstance.getState();
st.itemsInstance = ownerInstance.selectAllComponents('.' + classPrefix + '__drag-item');
st.list = newVal || [];
st.list.forEach(function (item, index) {
var itemIns = st.itemsInstance[index];
if (item && itemIns) {
itemIns.removeClass(classPrefix + '__drag--tran');
itemIns.setStyle({
transform: 'translate3d(' + item.tranX + ',' + item.tranY + ', 0)',
});
if (item.fixed) itemIns.addClass(classPrefix + '__drag--fixed');
}
});
dragCollisionList = [];
};
module.exports = {
longPress: longPress,
touchMove: touchMove,
touchEnd: touchEnd,
baseDataObserver: baseDataObserver,
listObserver: listObserver,
};

View File

@@ -0,0 +1,3 @@
import { TdUploadProps } from './type';
declare const props: TdUploadProps;
export default props;

View File

@@ -0,0 +1 @@
const props={addBtn:{type:Boolean,value:!0},addContent:{type:String},allowUploadDuplicateFile:{type:Boolean,value:!1},config:{type:Object},disabled:{type:null,value:void 0},draggable:{type:null},files:{type:Array,value:null},defaultFiles:{type:Array},gridConfig:{type:Object},gutter:{type:Number,value:16},imageProps:{type:Object},max:{type:Number,value:0},mediaType:{type:Array,value:["image","video"]},preview:{type:Boolean,value:!0},removeBtn:{type:Boolean,value:!0},requestMethod:{type:null},sizeLimit:{type:null},source:{type:String,value:"media"},transition:{type:Object,value:{backTransition:!0,duration:300,timingFunction:"ease"}}};export default props;

View File

@@ -0,0 +1,121 @@
import { ImageProps } from '../image/index';
export interface TdUploadProps {
addBtn?: {
type: BooleanConstructor;
value?: boolean;
};
addContent?: {
type: StringConstructor;
value?: string;
};
allowUploadDuplicateFile?: {
type: BooleanConstructor;
value?: boolean;
};
config?: {
type: ObjectConstructor;
value?: UploadMpConfig;
};
disabled?: {
type: BooleanConstructor;
value?: boolean;
};
draggable?: {
type: null;
value?: boolean | {
vibrate?: boolean;
collisionVibrate?: boolean;
};
};
files?: {
type: ArrayConstructor;
value?: Array<UploadFile>;
};
defaultFiles?: {
type: ArrayConstructor;
value?: Array<UploadFile>;
};
gridConfig?: {
type: ObjectConstructor;
value?: {
column?: number;
width?: number;
height?: number;
};
};
gutter?: {
type: NumberConstructor;
value?: number;
};
imageProps?: {
type: ObjectConstructor;
value?: ImageProps;
};
max?: {
type: NumberConstructor;
value?: number;
};
mediaType?: {
type: ArrayConstructor;
value?: Array<MediaType>;
};
preview?: {
type: BooleanConstructor;
value?: boolean;
};
removeBtn?: {
type: BooleanConstructor;
value?: boolean;
};
requestMethod?: {
type: undefined;
value?: null;
};
sizeLimit?: {
type: null;
value?: number | SizeLimitObj;
};
source?: {
type: StringConstructor;
value?: 'media' | 'messageFile';
};
transition?: {
type: ObjectConstructor;
value?: Transition;
};
}
export declare type UploadMpConfig = ImageConfig | VideoConfig;
export interface ImageConfig {
count?: number;
sizeType?: Array<SizeTypeValues>;
sourceType?: Array<SourceTypeValues>;
}
export declare type SizeTypeValues = 'original' | 'compressed';
export declare type SourceTypeValues = 'album' | 'camera';
export interface VideoConfig {
sourceType?: Array<SourceTypeValues>;
compressed?: boolean;
maxDuration?: number;
camera?: 'back' | 'front';
}
export interface UploadFile {
url: string;
name?: string;
size?: number;
type?: 'image' | 'video';
percent?: number;
status: 'loading' | 'reload' | 'failed' | 'done';
}
export declare type MediaType = 'image' | 'video';
export interface SizeLimitObj {
size: number;
unit: SizeUnit;
message?: string;
}
export declare type SizeUnitArray = ['B', 'KB', 'MB', 'GB'];
export declare type SizeUnit = SizeUnitArray[number];
export interface Transition {
backTransition?: boolean;
duration?: number;
timingFunction?: string;
}

View File

@@ -0,0 +1 @@
export{};

View File

@@ -0,0 +1 @@
{"key":"Upload","label":"上传","icon":"","properties":[{"key":"addContent","type":["String","TNode"],"defaultValue":"","desc":"添加按钮内容。值为空,使用默认图标渲染;值为 slot 则表示使用插槽渲染;其他值无效。","label":""},{"key":"config","type":["Object"],"defaultValue":"","desc":"图片上传配置,视频上传配置,文件上传配置等,包含图片尺寸、图片来源、视频来源、视频拍摄最长时间等。更多细节查看小程序官网。[图片上传](https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.chooseImage.html)。[视频上传](https://developers.weixin.qq.com/miniprogram/dev/api/media/video/wx.chooseVideo.html)","label":""},{"key":"deleteBtn","type":["String","TNode"],"defaultValue":"","desc":"删除图标。值为空,使用默认图标渲染;值为 slot 则表示使用插槽渲染;其他值无效。","label":""},{"key":"fileListDisplay","type":["TNode"],"defaultValue":"","desc":"【开发中】用于完全自定义文件列表内容","label":""},{"key":"files","type":["Array"],"defaultValue":"","desc":"已上传文件列表","label":""},{"key":"gridConfig","type":["Object"],"defaultValue":"","desc":"upload组件每行上传图片列数以及图片的宽度和高度","label":""},{"key":"gutter","type":["Number"],"defaultValue":"16","desc":"预览窗格的 gutter 大小,单位 rpx","label":""},{"key":"imageProps","type":["Object"],"defaultValue":"","desc":"透传 Image 组件全部属性","label":""},{"key":"max","type":["Number"],"defaultValue":"0","desc":"用于控制文件上传数量,值为 0 则不限制","label":""},{"key":"mediaType","type":["Array"],"defaultValue":"['image', 'video']","desc":"支持上传的文件类型,图片或视频","label":""},{"key":"requestMethod","type":["Function"],"defaultValue":"","desc":"自定义上传方法","label":""},{"key":"sizeLimit","type":["Number","Object"],"defaultValue":"","desc":"图片文件大小限制,单位 KB。可选单位有`'B' | 'KB' | 'MB' | 'GB'`。示例一:`1000`。示例二:`{ size: 2, unit: 'MB', message: '图片大小不超过 {sizeLimit} MB' }`","label":""}],"events":[{"key":"add","desc":"上传成功后触发,仅包含本次选择的照片;`context.url` 表示选定视频的临时文件路径 (本地路径)。`context.duration` 表示选定视频的时间长度。`context.size`选定视频的数据量大小。更多描述参考 wx.chooseMedia 小程序官网描述","label":""},{"key":"complete","desc":"上传成功或失败后触发","label":""},{"key":"fail","desc":"上传失败后触发","label":""},{"key":"remove","desc":"移除文件时触发","label":""},{"key":"selectChange","desc":"选择文件或图片之后,上传之前,触发该事件。<br />`params.value` 表示之前已经上传完成的文件列表。<br />`params.currentSelectedFiles` 表示本次上传选中的文件列表","label":""},{"key":"success","desc":"上传成功后触发,包含所有上传的文件;`context.url` 表示选定视频的临时文件路径 (本地路径)。`context.duration` 表示选定视频的时间长度。`context.size`选定视频的数据量大小。更多描述参考 wx.chooseMedia 小程序官网描述","label":""}]}

View File

@@ -0,0 +1,65 @@
/// <reference types="miniprogram-api-typings" />
import { SuperComponent } from '../common/src/index';
import { UploadFile } from './type';
export default class Upload extends SuperComponent {
externalClasses: string[];
options: {
multipleSlots: boolean;
};
data: {
classPrefix: string;
prefix: string;
current: boolean;
proofs: any[];
customFiles: UploadFile[];
customLimit: number;
column: number;
dragBaseData: {};
rows: number;
dragWrapStyle: string;
dragList: any[];
dragging: boolean;
dragLayout: boolean;
};
properties: import("./type").TdUploadProps;
controlledProps: {
key: string;
event: string;
}[];
observers: {
'files, max, draggable'(files: UploadFile, max: number): void;
gridConfig(): void;
};
lifetimes: {
ready(): void;
};
handleLimit(customFiles: UploadFile[], max: number): void;
triggerSuccessEvent(files: any): void;
triggerFailEvent(err: any): void;
onFileClick(e: WechatMiniprogram.BaseEvent): void;
getFileType(mediaType: string[], tempFilePath: string, fileType?: string): string;
getRandFileName(filePath: any): string;
onDelete(e: any): void;
deleteHandle(index: number): void;
updateGrid(): void;
resetDragLayout(): void;
initDragLayout(): void;
initDragList(): void;
initDragBaseData(): void;
methods: {
getPreviewMediaSources(): WechatMiniprogram.MediaSource[];
onPreview(e: WechatMiniprogram.BaseEvent): void;
onPreviewImage(e: WechatMiniprogram.BaseEvent): void;
onPreviewMedia(e: WechatMiniprogram.BaseEvent): void;
uploadFiles(files: UploadFile[]): Promise<unknown>;
startUpload(files: UploadFile[]): any;
onAddTap(): void;
chooseMedia(mediaType: any): void;
chooseMessageFile(mediaType: any): void;
afterSelect(files: any): void;
dragVibrate(e: any): void;
dragStatusChange(e: any): void;
dragEnd(e: any): void;
triggerDropEvent(files: any): void;
};
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"component":true,"styleIsolation":"apply-shared","usingComponents":{"t-grid":"../grid/grid","t-grid-item":"../grid-item/grid-item","t-icon":"../icon/icon","t-image":"../image/image"}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
module.exports.getWrapperAriaRole = function (file) {
return file.status && file.status != 'done' ? 'text' : 'button';
};
module.exports.getWrapperAriaLabel = function (file) {
if (file.status && file.status != 'done') {
if (file.status == 'loading') {
return file.percent ? '上传中:' + file.percent + '%' : '上传中';
} else {
return file.status == 'reload' ? '重新上传' : '上传失败';
}
} else {
return file.type === 'video' ? '视频' : '图像';
}
};

View File

@@ -0,0 +1,21 @@
@import '../common/style/index.wxss';.t-upload{position:relative;}
.t-upload__grid-content{padding:0;}
.t-upload__grid-file{position:relative;}
.t-upload__add-icon{width:100%;height:100%;display:none;align-items:center;justify-content:center;font-size:var(--td-upload-add-icon-font-size,56rpx);background-color:var(--td-upload-add-bg-color,var(--td-bg-color-secondarycontainer,var(--td-gray-color-1,#f3f3f3)));color:var(--td-upload-add-color,var(--td-text-color-placeholder,var(--td-font-gray-3,rgba(0,0,0,.4))));border-radius:var(--td-upload-radius,var(--td-radius-default,12rpx));}
.t-upload__add-icon--disabled{background-color:var(--td-upload-add-disabled-bg-color,var(--td-bg-color-component-disabled,var(--td-gray-color-2,#eee)));color:var(--td-upload-add-icon-disabled-color,var(--td-text-color-disabled,var(--td-font-gray-4,rgba(0,0,0,.26))));}
.t-upload__add-icon:only-child{display:flex;}
.t-upload__thumbnail{width:100%;height:100%;max-height:100%;overflow:hidden;}
.t-upload__wrapper{position:relative;border-radius:var(--td-upload-radius,var(--td-radius-default,12rpx));overflow:hidden;}
.t-upload__wrapper--disabled::before{content:'';position:absolute;top:0;left:0;width:100%;height:100%;background-color:var(--td-upload-disabled-mask,rgba(0,.6));z-index:1;}
.t-upload__close-btn{position:absolute;top:0;right:0;display:flex;align-items:center;justify-content:center;width:40rpx;height:40rpx;border-top-right-radius:var(--td-upload-radius,var(--td-radius-default,12rpx));border-bottom-left-radius:var(--td-upload-radius,var(--td-radius-default,12rpx));background-color:var(--td-font-gray-3,rgba(0,0,0,.4));}
.t-upload__progress-mask{position:absolute;left:0;top:0;width:100%;height:100%;background-color:var(--td-font-gray-2,rgba(0,0,0,.6));display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:var(--td-upload-radius,var(--td-radius-default,12rpx));color:var(--td-text-color-anti,var(--td-font-white-1,#fff));padding:32rpx 0;box-sizing:border-box;}
.t-upload__progress-text{font-size:24rpx;line-height:40rpx;margin-top:8rpx;}
.t-upload__progress-loading{animation:spin infinite linear .6s;}
.t-upload__drag{position:relative;width:100%;--td-grid-item-bg-color:transparent;}
.t-upload__drag-item{position:absolute;z-index:1;top:0;left:0;height:auto;width:100%;}
.t-upload__drag--fixed{z-index:0;}
.t-upload__drag--tran{transition-property:transform;transition-duration:var(--td-upload-drag-transition-duration);transition-timing-function:var(--td-upload-drag-transition-timing-function);}
.t-upload__drag--cur{z-index:var(--td-upload-drag-z-index,999);}
@keyframes spin{
0%{transform:rotate(0);}
100%{transform:rotate(360deg);}}