Files
2026-06-02 10:42:33 +08:00

482 lines
13 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="status-bar"></view>
<!-- 编辑模板弹窗 -->
<view class="popup-overlay">
<view class="popup-card">
<view class="close-popup-card"><view class="iconfont icon-quxiao"></view></view>
<view class="popup-title">编辑模板</view>
<view class="edit-template-wrapper">
<view class="edit-template-name">
<view>模板名称</view>
<input placeholder-style="请输入模板名称" v-model="templateName"/>
</view>
<view class="edit-template-name">
<view>模板内容</view>
<view class="markdown-editor-pane">
<view class="markdown-pane-header">
编辑
</view>
<textarea>
</textarea>
</view>
<view class="markdown-preview-pane">
<view class="markdown-pane-header">
预览
</view>
<view></view>
</view>
</view>
</view>
</view>
</view>
<view class="workspace-container page-container">
<view class="workspace-header">
<view class="custom-navbar">
<view class="navbar-left" @click="handleBackOrCheck ">
<view class="iconfont icon-fanhui custom-navbar-icon"></view>
<view class="navbar-before-title workspace-text">{{isSelectFolder?'全选':navbarBeforeTitle}}</view>
</view>
<view class="navbar-title workspace-text">{{navbarTitle}}</view>
<view class="navbar-right" v-if="checkTemplate">
<view v-if="isSelectFolder" class="navbar-right-text workspace-text" @click="handleSelectFolder()">
完成</view>
<view v-else class="iconfont icon-gengduo" :class="isMenuOpen ?'menu-open':'custom-navbar-icon'"
@click="handleMenu"></view>
</view>
<view v-if="isMenuOpen" class="menu-card">
<view class="menu-card-item" @click="handleSelectFolder();handleMenu()">选择</view>
<view class="solid-line"></view>
<view class="menu-card-item">新建模板</view>
<view class="solid-line"></view>
<view class="menu-card-item">上传模板</view>
</view>
</view>
<view class="search-file-warpper">
<view class="search-file">
<view class="iconfont icon-sousuo"></view>
<input class="search-file-input" placeholder="搜索" @focus="handleSearchFocus"
v-model="searchKeyword" />
</view>
<view v-if="isSearchFocus" class="cancel-search" @click="handleSearchFocus">取消</view>
</view>
</view>
<view class="folder-grid" v-if="!checkTemplate">
<view class="folder-item" @click="checkShowTemplate('all')">
<view class="iconfont icon-a-wenjianjiawenjian folder-item-style"></view>
<view class="folder-name">全部模板</view>
</view>
<view class="folder-item" @click="checkShowTemplate('like')">
<view class="iconfont icon-a-wenjianjiawenjian folder-item-style"></view>
<view class="folder-name">收藏模板</view>
</view>
</view>
<view class="workspace-content" v-if="checkTemplate">
<view class="folder-null" v-if="currentTemplateList.length===0">
<view class="iconfont icon-wenjianjia"></view>
暂无模板
</view>
<view class="template-grid" v-if="currentTemplateList.length>0">
<view class="template-card" v-for="(item,index) in currentTemplateList" :key="index">
<view class="template-name">{{item.name}}</view>
<view class="template-content">
<view class="template-content-text">
{{item.content}}
</view>
</view>
<view class="template-info-wrapper">
<view class="template-item">
<view class="template-time background-style">{{formatTime(item.modified_time)}}</view>
<view class="template-cache background-style">{{formatSize(item.size)}}</view>
</view>
<view class="template-option">
<view class="iconfont" :class="item.is_favorite ? 'icon-favorite-fill':'icon-favorite'"
@click="handleLikeTemplate(index)"></view>
<view class="iconfont icon-edit-fill" @click="editTemplate"></view>
<view class="iconfont icon-choose-fill"></view>
</view>
</view>
</view>
</view>
</view>
<view v-if="isSelectFolder" class="workspace-footer" :class="{'folder-actions':selectFileList.length>0}">
<view class="iconfont icon-shangchuan"></view>
<view class="iconfont icon-fuzhi"></view>
<view class="iconfont icon-wenjian"></view>
<view class="iconfont icon-del"></view>
<view class="iconfont icon-gengduo"></view>
</view>
</view>
</template>
<script setup>
import {
onMounted,
ref
} from 'vue';
// 格式化时间函数
const formatTime = (timestamp) => {
if (!timestamp) return ''
// 处理包含毫秒的时间戳
const seconds = Math.floor(timestamp)
const date = new Date(seconds * 1000)
const year = date.getFullYear()
const month = (date.getMonth() + 1).toString().padStart(2, '0')
const day = date.getDate().toString().padStart(2, '0')
const hours = date.getHours().toString().padStart(2, '0')
const minutes = date.getMinutes().toString().padStart(2, '0')
const seconds_part = date.getSeconds().toString().padStart(2, '0')
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds_part}`
}
// 转换字节大小
const formatSize = (bytes) => {
if (!bytes || bytes === 0) return '0 B'
const units = ['B', 'KB', 'MB', 'GB', 'TB']
let size = bytes
let unitIndex = 0
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024
unitIndex++
}
// 保留一位或两位小数
return `${size.toFixed(1)} ${units[unitIndex]}`
}
// 核心:点赞/取消点赞
const handleLikeTemplate = (index) => {
let targetItem
// 1. 根据当前展示类型,找到真实被点击的项
if (checkTemplate.value === 'all') {
// 全部列表:直接用 index
targetItem = allTemplate.value[index]
} else if (checkTemplate.value === 'like') {
// 收藏列表:先过滤出收藏项,再用 index 找到
const favoriteList = allTemplate.value.filter(item => item.is_favorite)
targetItem = favoriteList[index]
}
// 2. 切换收藏状态
if (targetItem) {
targetItem.is_favorite = !targetItem.is_favorite
}
// 3. 关键:切换后重新刷新当前列表(否则页面不更新)
if (checkTemplate.value === 'all') {
currentTemplateList.value = [...allTemplate.value]
} else {
currentTemplateList.value = allTemplate.value.filter(item => item.is_favorite)
}
}
// 编辑模板
const templateName = ref('aaa')
const editTemplate = () => {
console.log('点击了编辑模板');
}
// 选择的模板区全部or收藏
const checkTemplate = ref('')
const currentTemplateList = ref([])
const checkShowTemplate = (type) => {
checkTemplate.value = type;
if (type === 'all') {
navbarTitle.value = '全部模板'
currentTemplateList.value = allTemplate.value
}
if (type === 'like') {
navbarTitle.value = '收藏模板'
currentTemplateList.value = allTemplate.value.filter(item => item.is_favorite === true)
}
}
const navbarBeforeTitle = ref('');
const navbarTitle = ref('模板区');
// 选择文件模式
const isSelectFolder = ref(false);
const selectFileList = ref([]);
const handleSelectFolder = () => {
if (isSelectFolder.value) {
selectFileList.value = []
}
isSelectFolder.value = !isSelectFolder.value;
}
const selectFolder = (id) => {
const index = selectFileList.value.indexOf(id);
if (index !== -1) {
selectFileList.value.splice(index, 1);
} else {
selectFileList.value.push(id);
}
}
const handleLongPress = (folder) => {
if (isSelectFolder.value) return;
uni.showActionSheet({
itemList: ['重命名', '删除', '下载', '压缩'],
success: (res) => {
switch (res.tapIndex) {
case 0:
handleRename(folder);
break;
case 1:
handleDelete(folder);
break;
case 2:
handleDownload(folder);
break;
case 3:
handleDownload(folder);
break;
}
}
})
}
// 重命名
const handleRename = (folder) => {
uni.showModal({
title: '重命名',
content: '请输入新名称',
editable: true,
placeholderText: folder.name,
success: (res) => {
if (res.confirm && res.content) {
// 更新文件夹名称
updateFolderName(folder.id, res.content);
}
}
});
};
// 移动
const handleDownload = (folder) => {
// 可以选择跳转到移动页面或显示选择器
uni.showToast({
title: '移动功能开发中',
icon: 'none'
});
};
// 删除
const handleDelete = (folder) => {
uni.showModal({
title: '提示',
content: `确定要删除文件夹"${folder.name}"吗?`,
success: (res) => {
if (res.confirm) {
// deleteFolder(folder.id);
console.log('确认删除文件夹');
}
}
});
};
// const handleFolderClick = (id) => {
// console.log(id);
// }
// 菜单
const isMenuOpen = ref(false)
const handleMenu = () => {
isMenuOpen.value = !isMenuOpen.value;
}
// 搜索框
const searchKeyword = ref('')
const isSearchFocus = ref(false)
const handleSearchFocus = () => {
isSearchFocus.value = !isSearchFocus.value
}
const allTemplate = ref([{
"name": "SKILL.md",
"type": "file",
"path": "SKILL.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 4768,
"modified_time": 1776827361.9123552,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": 'khgvshbbthvgbihepiubjhrviifdhiuhrviuehrviuawhiuvrhy'
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 1776827666.9123552,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": 'khgvshbbthvgbihepiubjhiuvrhy'
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 1776827666.9123552,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": '该回家看了的法国红酒看来法帝国海军快来尝尝v吧给v复仇计划曝光vi计划日方提供与i哦的风格和健康'
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 1776827666.9123552,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": '的法国红酒看来法帝国海军快来尝尝v吧给'
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 1776827666.9123552,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": ''
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 1776827666.9123552,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": 'khgvshbbthvgbihepiubjhrviifdhiuhrviuehrviuawhiuvrhy'
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 1776827666.9123552,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": 'khgvshbbthvgbihepiubjhrviifdhiuhrviuehrviuawhiuvrhy'
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 1776827666.9123552,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": 'khgvshbbthvgbihepiubjhrviifdhiuhrviuehrviuawhiuvrhy'
},
{
"name": "222.md",
"type": "file",
"path": "222.md",
"children": [],
"file_count": 0,
"directory_count": 0,
"size": 5558,
"modified_time": 1776827666.9123552,
"extension": ".md",
"is_favorite": false,
"usage_count": 0,
"sort": 0,
"content": 'khgvshbbthvgbihepiubjhrviifdhiuhrviuehrviuawhiuvrhy'
}
])
// 全选/取消全选
const handleSelectAll = () => {
if (selectFileList.value.length === currentTemplateList.value.length) {
selectFileList.value = [];
} else {
selectFileList.value = currentTemplateList.value.map(f => f.id);
}
};
// 返回上一级
const handleBackOrCheck = () => {
if (isSelectFolder.value) {
// 选择模式下点击全选/取消全选
handleSelectAll();
return;
}
if (!isSelectFolder.value && currentTemplateList.value) {
currentTemplateList.value = []
checkTemplate.value = ''
navbarTitle.value = '模板区'
}
if (!isSelectFolder.value && !currentTemplateList.value) {
uni.navigateBack({
delta: 1,
fail() {
console.log("返回失败,进入兜底跳转")
uni.reLaunch({
url: '/pages/Chat/Chat'
})
}
})
}
};
</script>
<style scoped>
@import url('../WorkSpace.css');
@import url('TemplateSpace.css');
</style>