Selaa lähdekoodia

fix: 完成历史记录

zhangnuoyan 2 vuotta sitten
vanhempi
sitoutus
c8a3275834
3 muutettua tiedostoa jossa 371 lisäystä ja 73 poistoa
  1. 13 0
      src/assets/history/ok.svg
  2. 355 73
      src/components/History.vue
  3. 3 0
      src/views/Home.vue

+ 13 - 0
src/assets/history/ok.svg

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>确定</title>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="智能对话切图" transform="translate(-198, -195)">
+            <rect fill="" x="0" y="0" width="428" height="483"></rect>
+            <g id="编组备份-8" transform="translate(198, 195)">
+                <rect id="矩形" opacity="0.05" x="0" y="0" width="20" height="20" rx="3"></rect>
+                <path d="M17.8333337,4 L18.715095,4.88600055 L7.82967832,15.7193339 C7.58584523,15.9620003 7.19174958,15.9620002 6.94791667,15.7193335 L2,10.7950835 L2.881762,9.90908367 L7.387881,14.3950003 L17.8333337,4 Z" id="路径" fill="#FFFFFF" fill-rule="nonzero"></path>
+            </g>
+        </g>
+    </g>
+</svg>

+ 355 - 73
src/components/History.vue

@@ -20,7 +20,7 @@
                                 openSearch = true;
                             }
                         "
-                        v-show="!openSearch"
+                        :class="{ 'search-hide': openSearch }"
                     >
                         <img src="@/assets/history/search.svg" width="24" />
                     </div>
@@ -47,72 +47,218 @@
         </div>
         <div v-else>
             <section v-show="list.filter((v) => v.isTop).length > 0">
-                <div v-for="(item, key) in list.filter((v) => v.isTop)" :key="key">
-                    <p>{{ item.content }}</p>
-                    <p>
-                        <span>{{ item.time }}</span>
-                        <span>
-                            <a-tooltip content="取消置顶">
-                                <em @click="setTop(false, item.id)"><icon-to-bottom /></em>
-                            </a-tooltip>
-                            <a-tooltip content="重命名">
-                                <em><icon-edit /></em>
-                            </a-tooltip>
-                            <a-tooltip content="删除">
-                                <em @click="deleteItem(item.id)"><icon-delete /></em>
-                            </a-tooltip>
-                        </span>
-                    </p>
+                <div
+                    v-for="(item, key) in list.filter((v) => v.isTop)"
+                    :key="key"
+                    :class="{ 'div-padding': openDeletes }"
+                >
+                    <em
+                        v-if="openDeletes"
+                        @click="setSelect(item.id)"
+                        :class="{ 'select-icon': true, active: item.isSelected }"
+                    >
+                        <img src="@/assets/history/ok.svg" width="10" />
+                    </em>
+                    <div>
+                        <p :id="`history-${item.id}`">{{ item.content }}</p>
+                        <p>
+                            <span>{{ item.time }}</span>
+                            <span>
+                                <a-tooltip content="取消置顶">
+                                    <em @click="setTop(false, item.id)"><icon-to-bottom /></em>
+                                </a-tooltip>
+                                <a-tooltip content="重命名">
+                                    <em><icon-edit @click="editItem(item.id)" /></em>
+                                </a-tooltip>
+                                <a-popover :popup-visible="showDeleteTooltip && deleteId === item.id">
+                                    <a-tooltip content="删除">
+                                        <em @click="handleDeleteButton(item.id)"><icon-delete /></em>
+                                    </a-tooltip>
+                                    <template #content>
+                                        <p>删除后无法恢复,您是否删除?</p>
+                                        <div class="delete-buttons">
+                                            <div>
+                                                <a-button
+                                                    size="mini"
+                                                    type="primary"
+                                                    style="margin-right: 10px"
+                                                    @click="deleteItem(item.id)"
+                                                    >确认</a-button
+                                                >
+                                                <a-button
+                                                    size="mini"
+                                                    type="outline"
+                                                    @click="
+                                                        () => {
+                                                            showDeleteTooltip = false;
+                                                        }
+                                                    "
+                                                    >取消</a-button
+                                                >
+                                            </div>
+                                        </div>
+                                    </template>
+                                </a-popover>
+                            </span>
+                        </p>
+                    </div>
                 </div>
             </section>
             <section>
-                <div v-for="(item, key) in list.filter((v) => !v.isTop)" :key="key">
-                    <p>{{ item.content }}</p>
-                    <p>
-                        <span>{{ item.time }}</span>
-                        <span>
-                            <a-tooltip content="置顶">
-                                <em @click="setTop(true, item.id)"><icon-to-top /></em>
-                            </a-tooltip>
-                            <a-tooltip content="重命名">
-                                <em><icon-edit /></em>
-                            </a-tooltip>
-                            <a-tooltip content="删除">
-                                <em @click="deleteItem(item.id)"><icon-delete /></em>
-                            </a-tooltip>
-                        </span>
-                    </p>
+                <div
+                    v-for="(item, key) in list.filter((v) => !v.isTop)"
+                    :key="key"
+                    :class="{ 'div-padding': openDeletes }"
+                >
+                    <em
+                        v-if="openDeletes"
+                        @click="setSelect(item.id)"
+                        :class="{ 'select-icon': true, active: item.isSelected }"
+                    >
+                        <img src="@/assets/history/ok.svg" width="10" />
+                    </em>
+                    <div>
+                        <p :id="`history-${item.id}`">{{ item.content }}</p>
+                        <p>
+                            <span>{{ item.time }}</span>
+                            <span>
+                                <a-tooltip content="置顶">
+                                    <em @click="setTop(true, item.id)"><icon-to-top /></em>
+                                </a-tooltip>
+                                <a-tooltip content="重命名">
+                                    <em><icon-edit @click="editItem(item.id)" /></em>
+                                </a-tooltip>
+                                <a-popover :popup-visible="showDeleteTooltip && deleteId === item.id">
+                                    <a-tooltip content="删除">
+                                        <em @click="handleDeleteButton(item.id)"><icon-delete /></em>
+                                    </a-tooltip>
+                                    <template #content>
+                                        <p>删除后无法恢复,您是否删除?</p>
+                                        <div class="delete-buttons">
+                                            <div>
+                                                <a-button
+                                                    size="mini"
+                                                    type="primary"
+                                                    style="margin-right: 10px"
+                                                    @click="deleteItem(item.id)"
+                                                    >确认</a-button
+                                                >
+                                                <a-button
+                                                    size="mini"
+                                                    type="outline"
+                                                    @click="
+                                                        () => {
+                                                            showDeleteTooltip = false;
+                                                        }
+                                                    "
+                                                    >取消</a-button
+                                                >
+                                            </div>
+                                        </div>
+                                    </template>
+                                </a-popover>
+                            </span>
+                        </p>
+                    </div>
                 </div>
             </section>
         </div>
+        <footer v-if="list.length > 0">
+            <div
+                @click="
+                    () => {
+                        openDeletes = true;
+                    }
+                "
+                v-if="!openDeletes"
+            >
+                <icon-delete />
+                <span>批量删除</span>
+            </div>
+            <section v-else>
+                <div @click="setAllSelect">
+                    <em :class="{ 'select-icon': true, active: isAllSelected }">
+                        <img src="@/assets/history/ok.svg" width="10" />
+                    </em>
+                    <span>全选</span>
+                </div>
+                <div>
+                    <a-popover :popup-visible="showDeleteTooltip">
+                        <a-button
+                            size="mini"
+                            type="primary"
+                            status="danger"
+                            style="margin-right: 10px"
+                            @click="handleDeleteButton"
+                            >删除</a-button
+                        >
+                        <template #content>
+                            <div>
+                                <p>删除后无法恢复,您是否删除?</p>
+                                <div class="delete-buttons">
+                                    <div>
+                                        <a-button
+                                            size="mini"
+                                            type="primary"
+                                            style="margin-right: 10px"
+                                            @click="deleteItems"
+                                            >确认</a-button
+                                        >
+                                        <a-button
+                                            size="mini"
+                                            type="outline"
+                                            @click="
+                                                () => {
+                                                    showDeleteTooltip = false;
+                                                }
+                                            "
+                                            >取消</a-button
+                                        >
+                                    </div>
+                                </div>
+                            </div>
+                        </template>
+                    </a-popover>
+                    <a-button size="mini" type="outline" @click="exitSelects">退出</a-button>
+                </div>
+            </section>
+        </footer>
     </main>
 </template>
 <script>
 import { defineComponent, inject, onMounted, ref } from "vue";
 export default defineComponent({
     setup(props, { emit }) {
+        const { helper } = inject("$global");
         const openSearch = ref(false);
+        const openDeletes = ref(false);
+        const isAllSelected = ref(false);
+        const showDeleteTooltip = ref(false);
+        const deleteId = ref("");
         const list = ref([
             {
                 id: "1",
                 content:
                     " 1我希望你扮演一个广告词生成器。我会提供一段产品说明,根据说明撰写创意广告,根据不同的产品,提炼出关键信息并创造至少3个口号(slogan)。产品说明如下:(“电力看旅游”大数据产品,该数据产品系统梳理了各省旅游资源分布情况,通过横向比对景区用电情况,纵向分析月、周、节假日用电趋势,实现对区域旅游现状的评估和预估。) ",
                 time: " 2024-8-7 17:27:09 ",
-                isTop: true
+                isTop: true,
+                isSelected: false
             },
             {
                 id: "2",
                 content:
                     " 2我希望你扮演一个广告词生成器。我会提供一段产品说明,根据说明撰写创意广告,根据不同的产品,提炼出关键信息并创造至少3个口号(slogan)。产品说明如下:(“电力看旅游”大数据产品,该数据产品系统梳理了各省旅游资源分布情况,通过横向比对景区用电情况,纵向分析月、周、节假日用电趋势,实现对区域旅游现状的评估和预估。) ",
                 time: " 2024-8-7 17:27:09 ",
-                isTop: false
+                isTop: false,
+                isSelected: false
             },
             {
                 id: "3",
                 content:
                     " 3我希望你扮演一个广告词生成器。我会提供一段产品说明,根据说明撰写创意广告,根据不同的产品,提炼出关键信息并创造至少3个口号(slogan)。产品说明如下:(“电力看旅游”大数据产品,该数据产品系统梳理了各省旅游资源分布情况,通过横向比对景区用电情况,纵向分析月、周、节假日用电趋势,实现对区域旅游现状的评估和预估。) ",
                 time: " 2024-8-7 17:27:09 ",
-                isTop: false
+                isTop: false,
+                isSelected: false
             }
         ]);
         const setTop = (isTop, id) => {
@@ -122,21 +268,138 @@ export default defineComponent({
         const deleteItem = (id) => {
             const index = list.value.findIndex((item) => item.id === id);
             list.value.splice(index, 1);
+            showDeleteTooltip.value = false;
+        };
+        const setSelect = (id) => {
+            const index = list.value.findIndex((item) => item.id === id);
+            list.value[index].isSelected = !list.value[index].isSelected;
+            isAllSelected.value = list.value.every((item) => item.isSelected);
+        };
+        const setAllSelect = () => {
+            isAllSelected.value = !isAllSelected.value;
+            list.value.forEach((item) => (item.isSelected = isAllSelected.value));
+        };
+        const exitSelects = () => {
+            list.value.forEach((item) => (item.isSelected = false));
+            openDeletes.value = false;
+            isAllSelected.value = false;
+            showDeleteTooltip.value = false;
+        };
+        const handleDeleteButton = (id) => {
+            showDeleteTooltip.value = true;
+            deleteId.value = id;
+        };
+        const deleteItems = () => {
+            const ids = list.value.filter((item) => item.isSelected).map((item) => item.id);
+            ids.map((id) => {
+                deleteItem(id);
+            });
+            exitSelects();
+        };
+        const editItem = (id) => {
+            const index = list.value.findIndex((item) => item.id === id);
+            const div = document.getElementById(`history-${id}`);
+            const wrapDiv = div.cloneNode();
+            const { width, height, top, left } = div.getBoundingClientRect();
+            wrapDiv.style.width = `${width}px`;
+            wrapDiv.style.height = `${height}px`;
+            wrapDiv.style.top = `${top}px`;
+            wrapDiv.style.left = `${left}px`;
+            wrapDiv.style.position = "absolute";
+            const inputNode = document.createElement("input");
+            inputNode.value = list.value[index].content;
+            inputNode.style = "width: 100%;height: 100%";
+            wrapDiv.append(inputNode);
+            helper.setDialog(
+                true,
+                wrapDiv,
+                () => {
+                    inputNode.focus();
+                },
+                () => {
+                    list.value[index].content = inputNode.value;
+                }
+            );
         };
         return {
             openSearch,
+            handleDeleteButton,
             list,
             setTop,
-            deleteItem
+            editItem,
+            deleteItem,
+            isAllSelected,
+            openDeletes,
+            setAllSelect,
+            setSelect,
+            exitSelects,
+            showDeleteTooltip,
+            deleteItems,
+            deleteId
         };
     }
 });
 </script>
 <style scoped>
+.delete-buttons {
+    margin-top: 10px;
+    display: flex;
+    justify-content: center;
+}
 main {
     height: 100%;
     display: flex;
     flex-direction: column;
+    em.select-icon {
+        margin-right: 10px;
+        width: 14px;
+        height: 14px;
+        border: 1px solid #e3e3e3;
+        border-radius: 10px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        flex-shrink: 0;
+        > img {
+            display: none;
+        }
+        &.active {
+            background: #00aea3;
+            border: 1px solid #00aea3;
+            > img {
+                display: block;
+            }
+        }
+    }
+    > footer {
+        padding: 0 16px;
+        margin-bottom: 20px;
+        > div {
+            padding: 4px 8px;
+            border-radius: 4px;
+            display: inline-flex;
+            align-items: center;
+            cursor: pointer;
+            &:hover {
+                background: rgba(150, 171, 185, 0.2);
+            }
+            span {
+                margin-left: 5px;
+            }
+        }
+        > section {
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            > div {
+                display: flex;
+                align-items: center;
+                &:nth-child(1) {
+                    cursor: pointer;
+                }
+            }
+        }
+    }
     > header {
         > p {
             padding: 0 16px;
@@ -185,6 +448,13 @@ main {
                     align-items: center;
                     justify-content: center;
                     cursor: pointer;
+                    &.search-hide {
+                        width: 0;
+                        overflow: hidden;
+                        img {
+                            display: none;
+                        }
+                    }
                     &:hover {
                         opacity: 0.8;
                     }
@@ -226,47 +496,59 @@ main {
             > div {
                 padding: 8px 0;
                 cursor: pointer;
-
-                &:hover {
-                    p {
-                        color: #31c4c9 !important;
-                        &:nth-child(2) {
-                            > span {
-                                &:nth-child(2) {
-                                    opacity: 1;
+                overflow: hidden;
+                position: relative;
+                transition-duration: 0.2s;
+                &.div-padding {
+                    padding-left: 20px;
+                }
+                > em {
+                    position: absolute;
+                    top: 30px;
+                    left: 0;
+                }
+                > div {
+                    &:hover {
+                        p {
+                            color: #31c4c9 !important;
+                            &:nth-child(2) {
+                                > span {
+                                    &:nth-child(2) {
+                                        opacity: 1;
+                                    }
                                 }
                             }
                         }
                     }
-                }
-                > p {
-                    height: 28px;
-                    line-height: 28px;
-                    white-space: nowrap;
-                    overflow: hidden;
-                    text-overflow: ellipsis;
-                    &:nth-child(2) {
-                        color: #b4b6bb;
-                        display: flex;
-                        align-items: center;
-                        > span {
-                            &:nth-child(1) {
-                                flex: 1;
-                            }
-                            &:nth-child(2) {
-                                opacity: 0;
-                                display: flex;
-                                > em {
-                                    color: #000 !important;
+                    > p {
+                        height: 28px;
+                        line-height: 28px;
+                        white-space: nowrap;
+                        overflow: hidden;
+                        text-overflow: ellipsis;
+                        &:nth-child(2) {
+                            color: #b4b6bb;
+                            display: flex;
+                            align-items: center;
+                            > span {
+                                &:nth-child(1) {
+                                    flex: 1;
+                                }
+                                &:nth-child(2) {
+                                    opacity: 0;
                                     display: flex;
-                                    width: 25px;
-                                    height: 25px;
-                                    border-radius: 6px;
-                                    cursor: pointer;
-                                    align-items: center;
-                                    justify-content: center;
-                                    &:hover {
-                                        background: rgba(0, 0, 0, 0.05);
+                                    > em {
+                                        color: #000 !important;
+                                        display: flex;
+                                        width: 25px;
+                                        height: 25px;
+                                        border-radius: 6px;
+                                        cursor: pointer;
+                                        align-items: center;
+                                        justify-content: center;
+                                        &:hover {
+                                            background: rgba(0, 0, 0, 0.05);
+                                        }
                                     }
                                 }
                             }

+ 3 - 0
src/views/Home.vue

@@ -49,9 +49,12 @@ export default defineComponent({
     display: flex;
     .history-wrap {
         width: 0px;
+        opacity: 0;
         overflow: hidden;
         transition-duration: 0.3s;
+        transition-property: width;
         &-open {
+            opacity: 1;
             width: 260px;
         }
     }