|
@@ -16,48 +16,202 @@
|
|
</el-upload>
|
|
</el-upload>
|
|
<el-button @click="submit">上传</el-button>
|
|
<el-button @click="submit">上传</el-button>
|
|
|
|
|
|
- <div style="padding: 0 12px">
|
|
|
|
- <div style="display: inline-block; width: 10%">
|
|
|
|
- <el-card shadow="never"> qweqweqwe </el-card>
|
|
|
|
- </div>
|
|
|
|
- <div style="display: inline-block; width: 90%">
|
|
|
|
- <div style="display: flex; justify-content: flex-end; align-items: center">
|
|
|
|
- <el-button>确定</el-button>
|
|
|
|
- <el-button>确定</el-button>
|
|
|
|
- <el-button>确定</el-button>
|
|
|
|
- <el-button>确定</el-button>
|
|
|
|
|
|
+ <el-card>
|
|
|
|
+ <div style="display: flex">
|
|
|
|
+ <div style="width: 50%">
|
|
|
|
+ <button @click="handleSelectedItems">获取选中项</button>
|
|
|
|
+ <div class="demo-collapse">
|
|
|
|
+ <el-collapse v-model="activeNames">
|
|
|
|
+ <el-collapse-item v-for="(item, index) in data" :key="item.parentAsin" :name="String(index)">
|
|
|
|
+ <template #title>
|
|
|
|
+ <el-checkbox v-model="item.checked" @click.stop="stopOpen" @change="checkAll(item, item.checked)">{{ item.parentAsin }}</el-checkbox>
|
|
|
|
+ <el-tag style="margin-left: 8px" effect="plain" size="small" round>{{ item.num }}ASIN</el-tag>
|
|
|
|
+ </template>
|
|
|
|
+ <ul style="padding-left: 20px">
|
|
|
|
+ <li v-for="child in item.childAsin" :key="child.asin">
|
|
|
|
+ <div style="display: flex; align-items: center; margin-bottom: 10px">
|
|
|
|
+ <el-checkbox v-model="child.checked" @change="checkSingle(item)"></el-checkbox>
|
|
|
|
+ <!-- <img :src="child.image" style="width: 50px; height: 50px; margin-right: 10px" /> -->
|
|
|
|
+ <div>
|
|
|
|
+ <span>{{ child.Title }}</span>
|
|
|
|
+ <span>{{ child.asin }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </li>
|
|
|
|
+ </ul>
|
|
|
|
+ </el-collapse-item>
|
|
|
|
+ </el-collapse>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
- <div>
|
|
|
|
- <vxe-table round :data="tableData">
|
|
|
|
- <vxe-column resizable type="seq" width="60"></vxe-column>
|
|
|
|
- <vxe-column resizable field="name" title="Name"></vxe-column>
|
|
|
|
- <vxe-column resizable field="sex" title="Sex"></vxe-column>
|
|
|
|
- <vxe-column resizable field="age" title="Age"></vxe-column>
|
|
|
|
- </vxe-table>
|
|
|
|
|
|
+
|
|
|
|
+ <div style="width: 50%">
|
|
|
|
+ <!-- 在右侧面板的上方或下方添加这个按钮 -->
|
|
|
|
+ <button @click="removeSelectedItems">删除选中项</button>
|
|
|
|
+ <button @click="removeAllItems">删除所有</button>
|
|
|
|
+
|
|
|
|
+ <div class="demo-collapse">
|
|
|
|
+ <el-collapse v-model="activeNames">
|
|
|
|
+ <el-collapse-item v-for="(item, index) in selectedData" :key="item.parentAsin" :name="String(index)">
|
|
|
|
+ <template #title>
|
|
|
|
+ <el-checkbox v-model="item.checked" @click.stop="stopOpen" @change="checkAll(item, item.checked)">{{ item.parentAsin }}</el-checkbox>
|
|
|
|
+ <el-tag style="margin-left: 8px" effect="plain" size="small" round>{{ item.num }}ASIN</el-tag>
|
|
|
|
+ </template>
|
|
|
|
+ <ul style="padding-left: 20px">
|
|
|
|
+ <li v-for="child in item.childAsin" :key="child.asin">
|
|
|
|
+ <div style="display: flex; align-items: center; margin-bottom: 10px">
|
|
|
|
+ <el-checkbox v-model="child.checked" @change="checkSingle(item)"></el-checkbox>
|
|
|
|
+ <!-- <img :src="child.image" style="width: 50px; height: 50px; margin-right: 10px" /> -->
|
|
|
|
+ <div>
|
|
|
|
+ <span>{{ child.Title }}</span>
|
|
|
|
+ <span>{{ child.asin }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </li>
|
|
|
|
+ </ul>
|
|
|
|
+ </el-collapse-item>
|
|
|
|
+ </el-collapse>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
- <div>
|
|
|
|
- <p style="max-width: 100px; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: bottom; overflow: hidden;">
|
|
|
|
- 住在我心里孤独的 孤独的海怪 痛苦之王 开始厌倦 深海的光 停滞的海浪
|
|
|
|
- </p>
|
|
|
|
- </div>
|
|
|
|
|
|
+ </el-card>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
-import { ref, onMounted } from 'vue'
|
|
|
|
|
|
+import { ref, onMounted, computed } from 'vue'
|
|
import { useFs } from '@fast-crud/fast-crud'
|
|
import { useFs } from '@fast-crud/fast-crud'
|
|
import { createCrudOptions } from './crud'
|
|
import { createCrudOptions } from './crud'
|
|
-
|
|
|
|
import { request } from '/@/utils/service'
|
|
import { request } from '/@/utils/service'
|
|
-
|
|
|
|
import type { UploadProps, UploadUserFile, UploadFile, UploadFiles, UploadProgressEvent } from 'element-plus'
|
|
import type { UploadProps, UploadUserFile, UploadFile, UploadFiles, UploadProgressEvent } from 'element-plus'
|
|
-const tableData = ref([
|
|
|
|
- { id: 10001, name: 'Test1', role: 'Develop', sex: 'Man', age: 28, address: 'test abc' },
|
|
|
|
- { id: 10002, name: 'Test2', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },
|
|
|
|
- { id: 10003, name: 'Test3', role: 'PM', sex: 'Man', age: 32, address: 'Shanghai' },
|
|
|
|
- { id: 10004, name: 'Test4', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
|
|
|
|
|
|
+
|
|
|
|
+const data = ref([
|
|
|
|
+ {
|
|
|
|
+ parentAsin: '1ParentASIN',
|
|
|
|
+ checked: false,
|
|
|
|
+ childAsin: [
|
|
|
|
+ { asin: '1childASIN-1', image: 'http://xxxxxx.jpg', Title: '这是1childASIN-1', checked: false },
|
|
|
|
+ { asin: '1childASIN-2', image: 'http://xxxx.jpg', Title: '这是1childASIN-2', checked: false },
|
|
|
|
+ ],
|
|
|
|
+ num: 2,
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ parentAsin: '2ParentASIN',
|
|
|
|
+ checked: false,
|
|
|
|
+ childAsin: [
|
|
|
|
+ { asin: '2childASIN-1', image: 'http://xxxxx.jpg', Title: '这是2childASIN-1', checked: false },
|
|
|
|
+ { asin: '2childASIN-2', image: 'http://xxx.jpg', Title: '这是2childASIN-2', checked: false },
|
|
|
|
+ ],
|
|
|
|
+ num: 2,
|
|
|
|
+ },
|
|
])
|
|
])
|
|
|
|
+
|
|
|
|
+const activeNames = ref(data.value.map((_, index) => String(index)))
|
|
|
|
+
|
|
|
|
+function stopOpen() {
|
|
|
|
+ console.log(1213)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const checkAll = (parent, checked) => {
|
|
|
|
+ // 当选中或取消选中父级复选框时
|
|
|
|
+ parent.childAsin.forEach((child) => {
|
|
|
|
+ child.checked = checked
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function checkSingle(parent) {
|
|
|
|
+ // 当选中或取消选中单个子项复选框时
|
|
|
|
+ const allChecked = parent.childAsin.every((child) => child.checked)
|
|
|
|
+ parent.checked = allChecked
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function getSelectedItems() {
|
|
|
|
+ // 添加用于获取所有选中项的方法
|
|
|
|
+ const selectedItems = []
|
|
|
|
+ data.value.forEach((parentItem) => {
|
|
|
|
+ if (parentItem.checked) {
|
|
|
|
+ // 如果父项被选中,添加父项的值,并包含所有子项的完整数据
|
|
|
|
+ const children = parentItem.childAsin.map((childItem) => {
|
|
|
|
+ return { ...childItem } // 复制整个childItem对象
|
|
|
|
+ })
|
|
|
|
+ selectedItems.push({ parentAsin: parentItem.parentAsin, childAsin: children })
|
|
|
|
+ } else {
|
|
|
|
+ // 如果父项未被选中,仅添加被选中的子项的完整数据
|
|
|
|
+ const selectedChildren = parentItem.childAsin
|
|
|
|
+ .filter((childItem) => childItem.checked)
|
|
|
|
+ .map((childItem) => {
|
|
|
|
+ return { ...childItem } // 复制整个childItem对象
|
|
|
|
+ })
|
|
|
|
+ if (selectedChildren.length > 0) {
|
|
|
|
+ selectedItems.push({ parentAsin: parentItem.parentAsin, childAsin: selectedChildren })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ return selectedItems
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const selectedData = ref([])
|
|
|
|
+
|
|
|
|
+function handleSelectedItems() {
|
|
|
|
+ // 获取所有选中项的深拷贝并取消勾选状态
|
|
|
|
+ const newSelectedItems = getSelectedItems().map(item => ({
|
|
|
|
+ ...item,
|
|
|
|
+ checked: false, // 取消父项勾选状态
|
|
|
|
+ num: item.childAsin.length, // 更新子项数量
|
|
|
|
+ childAsin: item.childAsin.map(child => ({ ...child, checked: false })), // 取消子项勾选状态
|
|
|
|
+ }));
|
|
|
|
+
|
|
|
|
+ // 更新selectedData以包含新选中的项,如果项已存在,则合并子项,并确保不重复
|
|
|
|
+ newSelectedItems.forEach(newItem => {
|
|
|
|
+ const existingItemIndex = selectedData.value.findIndex(item => item.parentAsin === newItem.parentAsin);
|
|
|
|
+ if (existingItemIndex !== -1) {
|
|
|
|
+ // 合并子项,并确保不重复添加相同的子项
|
|
|
|
+ const existingChildren = selectedData.value[existingItemIndex].childAsin;
|
|
|
|
+ const newChildren = newItem.childAsin;
|
|
|
|
+ const mergedChildren = [...existingChildren];
|
|
|
|
+ newChildren.forEach(newChild => {
|
|
|
|
+ if (!mergedChildren.some(child => child.asin === newChild.asin)) {
|
|
|
|
+ mergedChildren.push(newChild);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 更新现有项的子项和子项数量
|
|
|
|
+ selectedData.value[existingItemIndex].childAsin = mergedChildren;
|
|
|
|
+ selectedData.value[existingItemIndex].num = mergedChildren.length; // 更新子项数量
|
|
|
|
+ } else {
|
|
|
|
+ // 如果不存在相同的父Asin,则添加新项
|
|
|
|
+ selectedData.value.push(newItem);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 清除原始数据的选中状态
|
|
|
|
+ clearSelections();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// 清除所有选中状态的辅助函数
|
|
|
|
+function clearSelections() {
|
|
|
|
+ data.value.forEach((parentItem) => {
|
|
|
|
+ parentItem.checked = false // 取消父项的选中状态
|
|
|
|
+ parentItem.childAsin.forEach((childItem) => {
|
|
|
|
+ childItem.checked = false // 取消子项的选中状态
|
|
|
|
+ })
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function removeSelectedItems() {
|
|
|
|
+ // 过滤掉所有被选中的项
|
|
|
|
+ selectedData.value = selectedData.value.filter((parentItem) => {
|
|
|
|
+ // 过滤掉父项下所有被选中的子项
|
|
|
|
+ parentItem.childAsin = parentItem.childAsin.filter((childItem) => !childItem.checked)
|
|
|
|
+ // 仅保留未被完全移除的父项(即至少有一个子项未被选中)
|
|
|
|
+ return parentItem.childAsin.length > 0
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 删除所有selectData的数据
|
|
|
|
+function removeAllItems() {
|
|
|
|
+ selectedData.value.splice(0)
|
|
|
|
+}
|
|
|
|
+
|
|
const fileList = ref<UploadUserFile[]>([])
|
|
const fileList = ref<UploadUserFile[]>([])
|
|
const onProgress = (evt: UploadProgressEvent, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
|
const onProgress = (evt: UploadProgressEvent, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
|
console.log(evt)
|
|
console.log(evt)
|