diff --git a/approval/delete-icon.svg b/approval/delete-icon.svg new file mode 100644 index 0000000..7a94db6 --- /dev/null +++ b/approval/delete-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/approval/grab-icon.svg b/approval/grab-icon.svg new file mode 100644 index 0000000..0db0b9b --- /dev/null +++ b/approval/grab-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/approval/index.js b/approval/index.js new file mode 100644 index 0000000..0378cae --- /dev/null +++ b/approval/index.js @@ -0,0 +1,124 @@ +Page({ + data: { + widgets: [ + { type: 'single-line-text', label: '单行文本' }, + { type: 'multi-line-text', label: '多行文本' }, + { type: 'description', label: '说明' }, + { type: 'number', label: '数字' }, + { type: 'currency', label: '金额' }, + { type: 'formula', label: '计算公式' } + ], + formItems: [], + touchStartY: null, + draggedItemIndex: null, + insertPosition: null + }, + + onLoad() { + console.log('页面加载'); + }, + + // 控件点击事件处理 + onWidgetTap(e) { + const widgetType = e.currentTarget.dataset.type; + const newItem = this.createFormItem(widgetType); + + const updatedFormItems = [...this.data.formItems, newItem]; + + this.setData({ + formItems: updatedFormItems + }); + }, + + // 创建表单项 + createFormItem(type) { + const itemMap = { + 'single-line-text': { + label: '单行文本', + type: 'text' + }, + 'multi-line-text': { + label: '多行文本', + type: 'textarea' + }, + 'number': { + label: '数字', + type: 'number' + }, + 'currency': { + label: '金额', + type: 'number' + }, + 'formula': { + label: '计算公式', + type: 'text' + }, + 'description': { + label: '说明', + type: 'text' + } + }; + + return { + ...itemMap[type], + unique: Date.now() + }; + }, + + // 移除表单项 + removeFormItem(e) { + const index = e.currentTarget.dataset.index; + const updatedFormItems = this.data.formItems.filter((_, i) => i !== index); + + this.setData({ + formItems: updatedFormItems + }); + }, + + // 触摸开始 + onTouchStart(e) { + this.setData({ + touchStartY: e.touches[0].clientY, + draggedItemIndex: e.currentTarget.dataset.index + }); + }, + + // 触摸移动 + onTouchMove(e) { + const { touchStartY, draggedItemIndex } = this.data; + const touchMoveY = e.touches[0].clientY; + const yDiff = touchMoveY - touchStartY; + + // 判断移动方向和距离 + if (Math.abs(yDiff) > 50) { + const { formItems } = this.data; + const newIndex = yDiff > 0 ? + parseInt(draggedItemIndex) + 1 : + parseInt(draggedItemIndex) - 1; + + // 确保新索引在数组范围内 + if (newIndex >= 0 && newIndex < formItems.length) { + // 交换位置 + const newFormItems = [...formItems]; + [newFormItems[draggedItemIndex], newFormItems[newIndex]] = + [newFormItems[newIndex], newFormItems[draggedItemIndex]]; + + this.setData({ + formItems: newFormItems, + touchStartY: touchMoveY, + draggedItemIndex: newIndex, + insertPosition: newIndex + }); + } + } + }, + + // 触摸结束 + onTouchEnd() { + this.setData({ + touchStartY: null, + draggedItemIndex: null, + insertPosition: null + }); + } +}); \ No newline at end of file diff --git a/approval/index.ttml b/approval/index.ttml new file mode 100644 index 0000000..c3b0c42 --- /dev/null +++ b/approval/index.ttml @@ -0,0 +1,119 @@ + + + 控件 + + 文本 + + 单行文本 + + + 多行文本 + + + 说明 + + + + 数值 + + 数字 + + + 金额 + + + 计算公式 + + + + + + 测试审批2 + 点击左侧控件自动新增 + + + + + + + + + + + + + + {{item.label}} + * + + + + + + \n\n请输入 + + + + 请输入 + + + + + + + + + + \ No newline at end of file diff --git a/approval/index.ttss b/approval/index.ttss new file mode 100644 index 0000000..cf30016 --- /dev/null +++ b/approval/index.ttss @@ -0,0 +1,195 @@ +.app-container { + display: flex; + height: 100vh; +} + +.widget-panel { + width: 30%; + padding: 15px; + background-color: #f9f9f9; + border-right: 1px solid #ddd; + overflow-y: auto; +} + +.panel-title { + font-size: 18px; + font-weight: bold; + margin-bottom: 15px; +} + +.control-group { + margin-bottom: 15px; +} + +.group-title { + font-weight: bold; + margin-bottom: 10px; + display: block; +} + +.widget { + margin: 5px 0; + padding: 10px; + background-color: #ffffff; + border: 1px solid #ccc; + border-radius: 4px; + text-align: center; + transition: transform 0.2s, box-shadow 0.2s; + cursor: pointer; /* 添加鼠标指针样式 */ + display: flex; + align-items: center; + justify-content: center; +} + +.widget:active { + transform: scale(0.95); +} + +.widget:hover { + transform: scale(1.05); + box-shadow: 0 2px 4px rgba(0,0,0,0.1); +} + +.widget-icon { + width: 20px; + height: 20px; + margin-right: 8px; + opacity: 0.7; +} + +.design-area { + flex: 1; + padding: 15px; + background-color: #f0f0f0; + display: flex; + flex-direction: column; + gap: 10px; + border-left: 1px solid #ddd; +} + +.drop-zone { + padding: 20px; + border: 2px dashed #ccc; + border-radius: 4px; + text-align: center; + color: #888; +} + +.form-item-wrapper { + position: relative; +} + +.insert-indicator { + position: absolute; + left: 0; + right: 0; + height: 2px; + background-color: #1890ff; + z-index: 100; /* 提高层级 */ + opacity: 1; /* 确保底线可见 */ + pointer-events: none; /* 防止底线阻挡交互 */ + transition: opacity 0.2s; /* 添加过渡效果 */ +} + +.form-item-wrapper:hover .insert-indicator, +.form-item-wrapper[data-dragging="true"] .insert-indicator { + opacity: 1; + visibility: visible; +} + +.form-item { + position: relative; + display: flex; + align-items: center; + background-color: white; + border: 1px solid #e0e0e0; + border-radius: 4px; + padding: 10px; + margin-bottom: 10px; + transition: transform 0.2s; + cursor: grab; +} + +.form-item[data-dragging="true"] { + transform: scale(1.05); + box-shadow: 0 4px 6px rgba(0,0,0,0.1); + z-index: 10; +} + +.drag-handle { + position: absolute; + left: 10px; + top: 50%; + transform: translateY(-50%); + display: flex; + align-items: center; + opacity: 0.6; + cursor: move; +} + +.grab-icon { + width: 20px; + height: 20px; +} + +.form-item-content { + display: flex; + flex-direction: column; + flex: 1; +} + +.form-item-label { + font-weight: bold; +} + +.required-mark { + color: red; + margin-left: 4px; +} + +.form-item-placeholder { + color: #999; + font-size: 12px; + text-align: right; +} + +.multi-line-placeholder { + color: #999; + font-size: 12px; + white-space: pre-line; + text-align: left; +} + +.remove-item { + position: absolute; + right: 10px; + color: #ff4d4f; + font-weight: bold; +} + +.remove-item:active { + color: #ff7875; +} + +.form-item[data-type="textarea"] .form-item-content { + min-height: 100px; +} + +.custom-cursor { + position: fixed; + pointer-events: none; + z-index: 9999; + transition: transform 0.1s; +} + +.custom-cursor-icon { + width: 24px; + height: 24px; + opacity: 0.8; +} + +.delete-icon { + width: 20px; + height: 20px; + opacity: 0.7; +} \ No newline at end of file