parent
							
								
									16dccb1f00
								
							
						
					
					
						commit
						da3f1638c6
					
				
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								@ -0,0 +1,359 @@
 | 
				
			||||
<template>
 | 
				
			||||
  <div v-if="visible">
 | 
				
			||||
    <div class="overlay" @click="close"></div>
 | 
				
			||||
    <transition name="slide">
 | 
				
			||||
      <div class="history-sidebar">
 | 
				
			||||
        <div class="history-header">
 | 
				
			||||
          <div class="title">💬对话历史</div>
 | 
				
			||||
        </div>
 | 
				
			||||
        <div class="create" v-if="!isHome" @click="createNew()">创建新对话</div>
 | 
				
			||||
 | 
				
			||||
        <!-- 判断是否有历史记录 -->
 | 
				
			||||
        <div v-if="historyList.length > 0" class="history-list-container">
 | 
				
			||||
          <ul class="history-list">
 | 
				
			||||
            <li
 | 
				
			||||
              v-for="(item, index) in historyList"
 | 
				
			||||
              :key="item.id || index"
 | 
				
			||||
              class="history-item"
 | 
				
			||||
              @click="onItemClick(item)"
 | 
				
			||||
            >
 | 
				
			||||
              <view v-if="isHome" class="activity-icon" :class="item.type">
 | 
				
			||||
                <image :src="getActivityIcon(item.type)" mode="aspectFit"></image>
 | 
				
			||||
              </view>
 | 
				
			||||
              <view v-if="isHome" class="activity-content">
 | 
				
			||||
                <view class="activity-title">{{ getWords(item.title) }}</view>
 | 
				
			||||
                <view class="activity-time">{{ item.updateTime }}</view>
 | 
				
			||||
              </view>
 | 
				
			||||
              <p v-if="!isHome" class="message-text">
 | 
				
			||||
                {{ getWords(item.title) }}
 | 
				
			||||
              </p>
 | 
				
			||||
            </li>
 | 
				
			||||
          </ul>
 | 
				
			||||
        </div>
 | 
				
			||||
 | 
				
			||||
        <!-- 没有数据时显示提示信息 -->
 | 
				
			||||
        <div v-else class="no-data">
 | 
				
			||||
          <image src="/static/icons/no-data.png" mode="aspectFit" class="no-data-icon" />
 | 
				
			||||
          <p class="no-data-text">暂无数据</p>
 | 
				
			||||
        </div>
 | 
				
			||||
 | 
				
			||||
      </div>
 | 
				
			||||
    </transition>
 | 
				
			||||
 | 
				
			||||
    <view class="animated-bg">
 | 
				
			||||
      <view
 | 
				
			||||
        v-for="i in 6"
 | 
				
			||||
        :key="i"
 | 
				
			||||
        class="bg-circle"
 | 
				
			||||
        :style="getRandomCircleStyle()"
 | 
				
			||||
      ></view>
 | 
				
			||||
    </view>
 | 
				
			||||
  </div>
 | 
				
			||||
</template>
 | 
				
			||||
 | 
				
			||||
<script>
 | 
				
			||||
export default {
 | 
				
			||||
  name: "ConversationHistory",
 | 
				
			||||
  props: {
 | 
				
			||||
    visible: { type: Boolean, required: true },
 | 
				
			||||
    historyList: { type: Array, default: () => [] },
 | 
				
			||||
    isHome: { type: Boolean, default: false },
 | 
				
			||||
  },
 | 
				
			||||
  mounted() {
 | 
				
			||||
    this.startCircleUpdate();
 | 
				
			||||
  },
 | 
				
			||||
  data() {
 | 
				
			||||
    return {
 | 
				
			||||
      circleStyle: this.getRandomCircleStyle(),
 | 
				
			||||
    };
 | 
				
			||||
  },
 | 
				
			||||
  methods: {
 | 
				
			||||
    close() {
 | 
				
			||||
      this.$emit("update:visible", false);
 | 
				
			||||
    },
 | 
				
			||||
    onItemClick(item) {
 | 
				
			||||
      this.$emit("select", item.id);
 | 
				
			||||
    },
 | 
				
			||||
    createNew() {
 | 
				
			||||
      console.log("Creating new conversation...");
 | 
				
			||||
      this.$emit("createNew");
 | 
				
			||||
      this.close();
 | 
				
			||||
    },
 | 
				
			||||
    // 生成随机背景圆圈样式
 | 
				
			||||
    getRandomCircleStyle() {
 | 
				
			||||
      const size = Math.random() * 300 + 100;
 | 
				
			||||
      const x = Math.random() * 100;
 | 
				
			||||
      const y = Math.random() * 100;
 | 
				
			||||
      const delay = Math.random() * 5;
 | 
				
			||||
      const duration = Math.random() * 10 + 15;
 | 
				
			||||
 | 
				
			||||
      return {
 | 
				
			||||
        width: `${size}rpx`,
 | 
				
			||||
        height: `${size}rpx`,
 | 
				
			||||
        left: `${x}%`,
 | 
				
			||||
        top: `${y}%`,
 | 
				
			||||
        animationDelay: `${delay}s`,
 | 
				
			||||
        animationDuration: `${duration}s`,
 | 
				
			||||
      };
 | 
				
			||||
    },
 | 
				
			||||
    startCircleUpdate() {
 | 
				
			||||
      setInterval(() => {
 | 
				
			||||
        this.circleStyle = this.getRandomCircleStyle();
 | 
				
			||||
      }, 5000); // 每 5 秒更新一次
 | 
				
			||||
    },
 | 
				
			||||
    getWords(text) {
 | 
				
			||||
      return text.length > 18 ? text.substring(0, 18) + "..." : text;
 | 
				
			||||
      // return text;
 | 
				
			||||
    },
 | 
				
			||||
    // 根据活动类型获取对应图标
 | 
				
			||||
    getActivityIcon(type) {
 | 
				
			||||
      const icons = {
 | 
				
			||||
        debate: "/static/icons/chat-1-line.png",
 | 
				
			||||
        argument: "/static/icons/lightbulb-line.png",
 | 
				
			||||
        review: "/static/icons/file-chart-line.png",
 | 
				
			||||
      };
 | 
				
			||||
      return icons[type] || icons.debate;
 | 
				
			||||
    },
 | 
				
			||||
  },
 | 
				
			||||
  unmounted() {
 | 
				
			||||
    clearInterval();
 | 
				
			||||
  },
 | 
				
			||||
};
 | 
				
			||||
</script>
 | 
				
			||||
 | 
				
			||||
<style scoped>
 | 
				
			||||
.no-data {
 | 
				
			||||
  display: flex;
 | 
				
			||||
  flex-direction: column;
 | 
				
			||||
  align-items: center;
 | 
				
			||||
  justify-content: center;
 | 
				
			||||
  padding-top: 50px;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.no-data-icon {
 | 
				
			||||
  width: 80px;
 | 
				
			||||
  height: 80px;
 | 
				
			||||
  opacity: 0.6;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.no-data-text {
 | 
				
			||||
  margin-top: 15px;
 | 
				
			||||
  font-size: 16px;
 | 
				
			||||
  color: #999;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.slide-enter-active,
 | 
				
			||||
.slide-leave-active {
 | 
				
			||||
  transition: all 0.4s ease;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.slide-enter-from,
 | 
				
			||||
.slide-leave-to {
 | 
				
			||||
  transform: translateX(-100%);
 | 
				
			||||
  opacity: 0;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.slide-enter-to,
 | 
				
			||||
.slide-leave-from {
 | 
				
			||||
  transform: translateX(0);
 | 
				
			||||
  opacity: 1;
 | 
				
			||||
}
 | 
				
			||||
.title {
 | 
				
			||||
  font-size: 24px;
 | 
				
			||||
  font-weight: bold;
 | 
				
			||||
  justify-content: center;
 | 
				
			||||
  align-content: center;
 | 
				
			||||
  color: #ffffff;
 | 
				
			||||
  margin-bottom: 10px;
 | 
				
			||||
}
 | 
				
			||||
.activity-icon {
 | 
				
			||||
  width: 60rpx;
 | 
				
			||||
  height: 60rpx;
 | 
				
			||||
  border-radius: 16rpx;
 | 
				
			||||
  display: flex;
 | 
				
			||||
  align-items: center;
 | 
				
			||||
  justify-content: center;
 | 
				
			||||
  margin-right: 16rpx;
 | 
				
			||||
}
 | 
				
			||||
.activity-content {
 | 
				
			||||
  flex: 1;
 | 
				
			||||
}
 | 
				
			||||
.activity-icon.debate {
 | 
				
			||||
  background: rgba(245, 158, 11, 0.3);
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.activity-icon.argument {
 | 
				
			||||
  background: rgba(16, 185, 129, 0.3);
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.activity-icon.review {
 | 
				
			||||
  background: rgba(79, 70, 229, 0.3);
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.activity-icon image {
 | 
				
			||||
  width: 36rpx;
 | 
				
			||||
  height: 36rpx;
 | 
				
			||||
  filter: brightness(0) invert(1);
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.activity-content {
 | 
				
			||||
  flex: 1;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.activity-title {
 | 
				
			||||
  font-size: 28rpx;
 | 
				
			||||
  color: #ffffff;
 | 
				
			||||
  margin-bottom: 6rpx;
 | 
				
			||||
}
 | 
				
			||||
.activity-time {
 | 
				
			||||
  font-size: 22rpx;
 | 
				
			||||
  color: rgba(255, 255, 255, 0.6);
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.overlay {
 | 
				
			||||
  position: fixed;
 | 
				
			||||
  top: 0;
 | 
				
			||||
  left: 0;
 | 
				
			||||
  width: 100vw;
 | 
				
			||||
  height: 100vh;
 | 
				
			||||
  background: rgba(0, 0, 0, 0.4);
 | 
				
			||||
  z-index: 500;
 | 
				
			||||
  backdrop-filter: blur(4px);
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.history-sidebar {
 | 
				
			||||
  position: absolute;
 | 
				
			||||
  top: 0;
 | 
				
			||||
  left: 0;
 | 
				
			||||
  width: 300px;
 | 
				
			||||
  height: 100vh;
 | 
				
			||||
 | 
				
			||||
  background-color: #7951dd;
 | 
				
			||||
  box-shadow: -6px 0 12px rgba(0, 0, 0, 0.2);
 | 
				
			||||
  padding: 24px 20px;
 | 
				
			||||
  overflow-y: auto;
 | 
				
			||||
  z-index: 800;
 | 
				
			||||
  border-top-left-radius: 12px;
 | 
				
			||||
  border-bottom-left-radius: 12px;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.history-header {
 | 
				
			||||
  display: flex;
 | 
				
			||||
  justify-content: center;
 | 
				
			||||
  align-items: center;
 | 
				
			||||
 | 
				
			||||
  margin-bottom: 20px;
 | 
				
			||||
  font-weight: 600;
 | 
				
			||||
  letter-spacing: 1px;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.create {
 | 
				
			||||
  font-size: 18px;
 | 
				
			||||
  font-weight: bold;
 | 
				
			||||
  color: #ffffff;
 | 
				
			||||
  background-color: #9269f9;
 | 
				
			||||
  width: 120px;
 | 
				
			||||
  height: 40px;
 | 
				
			||||
  border-radius: 20px;
 | 
				
			||||
  display: flex;
 | 
				
			||||
  justify-content: center;
 | 
				
			||||
  align-items: center;
 | 
				
			||||
  margin-bottom: 20px;
 | 
				
			||||
  cursor: pointer;
 | 
				
			||||
  transition: all 0.2s ease; /* 平滑过渡 */
 | 
				
			||||
 | 
				
			||||
  z-index: 999;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
/* 添加点击时的动画效果 */
 | 
				
			||||
.create:active {
 | 
				
			||||
  animation: clickEffect 0.5s ease forwards;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
/* 定义动画:点击时缩小一点并加深背景颜色 */
 | 
				
			||||
@keyframes clickEffect {
 | 
				
			||||
  0% {
 | 
				
			||||
    transform: scale(1);
 | 
				
			||||
    background-color: #9269f9;
 | 
				
			||||
  }
 | 
				
			||||
  50% {
 | 
				
			||||
    transform: scale(0.95);
 | 
				
			||||
    background-color: #7a54d8;
 | 
				
			||||
  }
 | 
				
			||||
  100% {
 | 
				
			||||
    transform: scale(1);
 | 
				
			||||
    background-color: #9269f9;
 | 
				
			||||
  }
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.history-list {
 | 
				
			||||
  list-style: none;
 | 
				
			||||
  padding: 0;
 | 
				
			||||
  margin: 0;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.history-item {
 | 
				
			||||
  display: flex;
 | 
				
			||||
 | 
				
			||||
  margin-bottom: 15px;
 | 
				
			||||
  padding: 12px 16px;
 | 
				
			||||
  background-color: rgba(255, 255, 255, 0.1);
 | 
				
			||||
  border-radius: 8px;
 | 
				
			||||
  cursor: pointer;
 | 
				
			||||
  transition: all 0.3s ease;
 | 
				
			||||
 | 
				
			||||
  z-index: 1001;
 | 
				
			||||
 | 
				
			||||
  will-change: background-color, transform;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.history-item:hover {
 | 
				
			||||
  background-color: rgba(255, 255, 255, 0.2);
 | 
				
			||||
  transform: scale(1.02);
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.message-text {
 | 
				
			||||
  color: #ffffff;
 | 
				
			||||
  margin: 0;
 | 
				
			||||
  font-size: 15px;
 | 
				
			||||
  word-break: break-word;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.slide-fade-enter-active,
 | 
				
			||||
.slide-fade-leave-active {
 | 
				
			||||
  transition: all 0.4s ease;
 | 
				
			||||
}
 | 
				
			||||
.slide-fade-enter {
 | 
				
			||||
  transform: translateX(100%);
 | 
				
			||||
  opacity: 0;
 | 
				
			||||
}
 | 
				
			||||
.slide-fade-leave-to {
 | 
				
			||||
  transform: translateX(100%);
 | 
				
			||||
  opacity: 0;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
/* 动态背景 */
 | 
				
			||||
.animated-bg {
 | 
				
			||||
  position: absolute;
 | 
				
			||||
  top: 0;
 | 
				
			||||
  left: 0;
 | 
				
			||||
  width: 340px;
 | 
				
			||||
  height: 100%;
 | 
				
			||||
  overflow: hidden;
 | 
				
			||||
  z-index: 600;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
.bg-circle {
 | 
				
			||||
  position: absolute;
 | 
				
			||||
  border-radius: 50%;
 | 
				
			||||
  background: linear-gradient(
 | 
				
			||||
    135deg,
 | 
				
			||||
    rgba(255, 255, 255, 0.05),
 | 
				
			||||
    rgba(255, 255, 255, 0.02)
 | 
				
			||||
  );
 | 
				
			||||
  animation: float 20s infinite ease-in-out;
 | 
				
			||||
  opacity: 0.4;
 | 
				
			||||
  /* 添加过渡效果 */
 | 
				
			||||
  transition: all 1.5s ease-in-out;
 | 
				
			||||
}
 | 
				
			||||
</style>
 | 
				
			||||
| 
		 After Width: | Height: | Size: 1.4 KiB  | 
| 
		 After Width: | Height: | Size: 20 KiB  | 
@ -1,13 +1,27 @@
 | 
				
			||||
// stores/argumentStore.ts
 | 
				
			||||
import { defineStore } from 'pinia'
 | 
				
			||||
import { defineStore } from "pinia";
 | 
				
			||||
 | 
				
			||||
export const useArgumentStore = defineStore('argument', {
 | 
				
			||||
export const useArgumentStore = defineStore("argument", {
 | 
				
			||||
  state: () => ({
 | 
				
			||||
    selectedArgument: null
 | 
				
			||||
    conversationId: -1,
 | 
				
			||||
    selectedArgument: "",
 | 
				
			||||
    conversation: [
 | 
				
			||||
      {
 | 
				
			||||
        role: "ai",
 | 
				
			||||
        content:
 | 
				
			||||
          "哈喽~ 我是辩论助手,很高兴为你服务!请告诉我你想立论的立场和题目。",
 | 
				
			||||
      },
 | 
				
			||||
    ],
 | 
				
			||||
  }),
 | 
				
			||||
  actions: {
 | 
				
			||||
    setArgument(arg) {
 | 
				
			||||
      this.selectedArgument = arg
 | 
				
			||||
    }
 | 
				
			||||
  }
 | 
				
			||||
})
 | 
				
			||||
      this.selectedArgument = arg;
 | 
				
			||||
    },
 | 
				
			||||
    setConversationId(id) {
 | 
				
			||||
      this.conversationId = id;
 | 
				
			||||
    },
 | 
				
			||||
    setConversation(conversation) {
 | 
				
			||||
      this.conversation = conversation;
 | 
				
			||||
    },
 | 
				
			||||
  },
 | 
				
			||||
});
 | 
				
			||||
 | 
				
			||||
@ -0,0 +1,23 @@
 | 
				
			||||
// stores/argumentStore.ts
 | 
				
			||||
import { defineStore } from "pinia";
 | 
				
			||||
 | 
				
			||||
export const useReviewStore = defineStore("review", {
 | 
				
			||||
  state: () => ({
 | 
				
			||||
    conversationId: -1,
 | 
				
			||||
    conversation: [
 | 
				
			||||
      {
 | 
				
			||||
        role: "ai",
 | 
				
			||||
        content:
 | 
				
			||||
          "哈喽~ 我是辩论助手,很高兴为你服务!请告诉我你想立论的立场和题目。",
 | 
				
			||||
      },
 | 
				
			||||
    ],
 | 
				
			||||
  }),
 | 
				
			||||
  actions: {
 | 
				
			||||
    setConversationId(id) {
 | 
				
			||||
      this.conversationId = id;
 | 
				
			||||
    },
 | 
				
			||||
    setConversation(conversation) {
 | 
				
			||||
      this.conversation = conversation;
 | 
				
			||||
    },
 | 
				
			||||
  },
 | 
				
			||||
});
 | 
				
			||||
@ -0,0 +1,15 @@
 | 
				
			||||
// stores/DebateStore.ts
 | 
				
			||||
import { defineStore } from 'pinia'
 | 
				
			||||
 | 
				
			||||
export const useTokenStore = defineStore('token', {
 | 
				
			||||
  state: () => ({
 | 
				
			||||
    token: {
 | 
				
			||||
      content: '',
 | 
				
			||||
    },
 | 
				
			||||
  }),
 | 
				
			||||
  actions: {
 | 
				
			||||
    setToken(content) {
 | 
				
			||||
      this.token.content = content;
 | 
				
			||||
    }
 | 
				
			||||
  }
 | 
				
			||||
});
 | 
				
			||||
					Loading…
					
					
				
		Reference in new issue