368 lines
11 KiB
Vue
368 lines
11 KiB
Vue
<script setup lang="ts">
|
|
import { formatFileSize } from '@/utils/index.ts'
|
|
import { uploadFileBatches } from '@/utils/uploadImg'
|
|
|
|
import { useMessage } from 'naive-ui'
|
|
import { onMounted } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
|
|
interface MemberItem {
|
|
communityId: number
|
|
createTime: string
|
|
downloadFileUser: {
|
|
avatarList: string[]
|
|
count: number
|
|
}
|
|
fileName: string
|
|
fileSize: number
|
|
id: number
|
|
tenantId: number
|
|
uploadUserName: string
|
|
}
|
|
|
|
definePageMeta({
|
|
layout: 'planet',
|
|
})
|
|
|
|
const route = useRoute()
|
|
const message = useMessage()
|
|
const memberList = ref<MemberItem[]>([])
|
|
const loading = ref(false)
|
|
const isInitialized = ref(false)
|
|
const params = ref({
|
|
orderByColum: '',
|
|
pageNum: 1,
|
|
pageSize: 2,
|
|
communityId: route.query.communityId,
|
|
tenantId: route.query.tenantId,
|
|
search: '',
|
|
})
|
|
|
|
// 添加分页数据
|
|
const pagination = ref({
|
|
page: 1,
|
|
pageSize: 2,
|
|
itemCount: 0,
|
|
showSizePicker: false,
|
|
})
|
|
|
|
// 处理分页变化
|
|
function handlePageChange(page: number) {
|
|
pagination.value.page = page
|
|
params.value.pageNum = page
|
|
getMemberList()
|
|
}
|
|
|
|
// 处理搜索
|
|
function handleSearch(e: KeyboardEvent) {
|
|
if (e.key === 'Enter') {
|
|
params.value.pageNum = 1
|
|
pagination.value.page = 1
|
|
getMemberList()
|
|
}
|
|
}
|
|
|
|
// 获取成员列表
|
|
async function getMemberList() {
|
|
try {
|
|
loading.value = true
|
|
const res = await request.post('/communityFile/list', params.value)
|
|
if (res.code === 200) {
|
|
memberList.value = res.rows
|
|
pagination.value.itemCount = res.total
|
|
isInitialized.value = true
|
|
}
|
|
}
|
|
catch (error) {
|
|
console.error(error)
|
|
}
|
|
finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
getMemberList()
|
|
})
|
|
|
|
// 下载文件
|
|
async function handleSetAdmin(item: MemberItem) {
|
|
const { id, fileName } = item
|
|
const res = await request.post('/communityFile/download', {
|
|
communityId: route.query.communityId,
|
|
tenantId: route.query.tenantId,
|
|
fileId: id,
|
|
})
|
|
if (res.code === 200) {
|
|
const { data } = res
|
|
// 创建临时下载链接
|
|
const link = document.createElement('a')
|
|
link.href = data
|
|
link.download = fileName // 使用原始文件名
|
|
link.style.display = 'none'
|
|
document.body.appendChild(link)
|
|
link.click()
|
|
document.body.removeChild(link)
|
|
}
|
|
}
|
|
|
|
// 复制文本到剪贴板
|
|
function copyToClipboard(text: string) {
|
|
navigator.clipboard.writeText(text).then(() => {
|
|
message.success('复制成功')
|
|
}).catch(() => {
|
|
message.error('复制失败')
|
|
})
|
|
}
|
|
|
|
const pictureInput = ref<HTMLInputElement | null>(null)
|
|
function handlePictureInput() {
|
|
pictureInput.value?.click()
|
|
}
|
|
|
|
// 允许的文件类型
|
|
const allowedFileTypes = [
|
|
'application/pdf',
|
|
'application/msword',
|
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
'application/vnd.ms-excel',
|
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
'application/vnd.ms-powerpoint',
|
|
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
'text/plain',
|
|
'application/zip',
|
|
]
|
|
|
|
async function handlePictureChange(event: Event) {
|
|
const files = (event.target as HTMLInputElement).files
|
|
if (!files || files.length === 0)
|
|
return
|
|
|
|
if (files.length > 1) {
|
|
message.error('只能选择 1 个文件')
|
|
return
|
|
}
|
|
|
|
const file = files[0]
|
|
if (!allowedFileTypes.includes(file.type)) {
|
|
message.error('只支持 PDF、Word、Excel、PPT、TXT 和 ZIP 文件')
|
|
return
|
|
}
|
|
|
|
try {
|
|
const res = await uploadFileBatches([file])
|
|
;(event.target as HTMLInputElement).value = ''
|
|
const { fileName, objectKey, path, size } = res[0]
|
|
const res1 = await request.post('/communityFile/upload', {
|
|
communityId: route.query.communityId,
|
|
tenantId: route.query.tenantId,
|
|
fileName,
|
|
objectKey,
|
|
fileSize: size,
|
|
fileUrl: path,
|
|
})
|
|
if (res1.code === 200) {
|
|
message.success('文件上传成功')
|
|
params.value.search = ''
|
|
params.value.pageNum = 1
|
|
pagination.value.page = 1
|
|
getMemberList()
|
|
}
|
|
}
|
|
catch (error) {
|
|
console.error(error)
|
|
message.error('文件上传失败')
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="min-h-screen bg-[#F7F8FA] px-10 py-6 flex gap-4">
|
|
<div class="bg-white rounded-lg flex-1">
|
|
<div class="flex justify-between items-center m-3 text-sm">
|
|
<div class="flex items-center gap-2">
|
|
<div class="bg-[#328afe] text-white px-3 py-1 rounded-sm cursor-pointer" @click="handlePictureInput">
|
|
上传文件
|
|
</div>
|
|
<div>
|
|
<!-- 111 -->
|
|
</div>
|
|
</div>
|
|
<div class="relative flex items-center w-[300px]">
|
|
<input
|
|
v-model="params.search"
|
|
type="text"
|
|
placeholder="请输入文件名"
|
|
class="w-full h-9 pl-4 pr-14 border border-[#eee] rounded-lg text-sm placeholder-[#878D95] outline-none focus:border-[#3f7ef7] focus:ring-1 focus:ring-[#3f7ef7] transition-colors"
|
|
@keyup="handleSearch"
|
|
>
|
|
<button class="absolute right-3 flex items-center space-x-1 text-[#4A5563]">
|
|
<svg class="w-4 h-4" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M7.333 12.667A5.333 5.333 0 1 0 7.333 2a5.333 5.333 0 0 0 0 10.667zM14 14l-2.9-2.9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
</svg>
|
|
<!-- <span class="text-sm font-bold">搜索</span> -->
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="grid grid-cols-[300px_150px_150px_200px_130px_100px] border-b border-[#eee]">
|
|
<div class="p-3 text-[#1f2329] font-medium">
|
|
全部文件
|
|
</div>
|
|
<div class="p-3 text-[#1f2329] font-medium">
|
|
文件大小
|
|
</div>
|
|
<div class="p-3 text-[#1f2329] font-medium">
|
|
上传人
|
|
</div>
|
|
<div class="p-3 text-[#1f2329] font-medium">
|
|
上传时间
|
|
</div>
|
|
<div class="p-3 text-[#1f2329] font-medium">
|
|
下载次数
|
|
</div>
|
|
<div class="p-3 text-[#1f2329] font-medium">
|
|
操作
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="loading" class="p-10">
|
|
<n-spin />
|
|
</div>
|
|
|
|
<template v-else>
|
|
<div
|
|
v-for="item in memberList"
|
|
:key="item.id"
|
|
class="grid grid-cols-[300px_150px_150px_200px_130px_100px] border-b border-[#eee] hover:bg-gray-50"
|
|
>
|
|
<div class="p-3 flex items-center gap-2">
|
|
<!-- <img :src="item.avatar" class="w-8 h-8 rounded-full" :alt="item.nickname"> -->
|
|
<span
|
|
class="truncate flex-1 cursor-pointer"
|
|
:title="item.fileName"
|
|
@dblclick="copyToClipboard(item.fileName)"
|
|
>
|
|
{{ item.fileName }}
|
|
</span>
|
|
</div>
|
|
<div class="p-3 flex items-center">
|
|
{{ formatFileSize(item.fileSize) }}
|
|
</div>
|
|
<div class="p-3 flex items-center">
|
|
{{ item.uploadUserName || '-' }}
|
|
</div>
|
|
<div class="p-3 flex items-center">
|
|
{{ item.createTime }}
|
|
</div>
|
|
|
|
<div class="p-3 flex items-center">
|
|
{{ item.downloadFileUser.count }}
|
|
</div>
|
|
<div class="p-3 flex items-center">
|
|
<div class="w-[100px]">
|
|
<button
|
|
class="text-[#1e80ff] hover:text-[#3b8fff]"
|
|
@click="handleSetAdmin(item)"
|
|
>
|
|
下载
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<div v-if="isInitialized && memberList.length > 0" class="flex justify-center mt-4">
|
|
<n-pagination
|
|
v-model:page="pagination.page"
|
|
v-model:page-size="pagination.pageSize"
|
|
:item-count="pagination.itemCount"
|
|
:show-size-picker="false"
|
|
@update:page="handlePageChange"
|
|
/>
|
|
</div>
|
|
<div v-else class="flex justify-center mt-10">
|
|
暂无数据
|
|
</div>
|
|
<input
|
|
ref="pictureInput"
|
|
type="file"
|
|
accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.zip"
|
|
class="hidden"
|
|
@change="handlePictureChange"
|
|
>
|
|
</div>
|
|
<div class="w-[300px]">
|
|
<PlanetBaseInfo :community-id="route.query.communityId" :tenant-id="route.query.tenantId" />
|
|
</div>
|
|
|
|
<!-- <n-modal
|
|
v-model:show="showBlackModal"
|
|
:style="{ width: '480px' }"
|
|
:mask-closable="false"
|
|
class="rounded-lg"
|
|
>
|
|
<div class="p-6 bg-white rounded-lg">
|
|
<div class="text-center text-lg font-medium mb-6">
|
|
拉黑成员
|
|
</div>
|
|
<n-form
|
|
ref="formRef"
|
|
:model="blackForm"
|
|
:rules="rules"
|
|
label-placement="left"
|
|
label-width="auto"
|
|
require-mark-placement="right-hanging"
|
|
class="space-y-4"
|
|
>
|
|
<n-form-item label="拉黑时长" path="blackDay">
|
|
<div class="flex items-center gap-2">
|
|
<n-input-number
|
|
v-model:value="blackForm.blackDay"
|
|
placeholder="请输入"
|
|
:min="1"
|
|
@update:value="() => formRef.value?.validate(['blackDay'])"
|
|
/>
|
|
<span class="text-sm">天</span>
|
|
<div class="relative group">
|
|
<div class="i-carbon-information text-gray-400 cursor-help" />
|
|
<div class="absolute left-6 top-0 hidden group-hover:block w-64 p-3 bg-black bg-opacity-75 text-white text-xs rounded-lg">
|
|
拉黑后该成员将不能对星球进行内容发布、点赞、评论内容等操作!拉黑时长结束后将自动解除
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</n-form-item>
|
|
<n-form-item label="拉黑原因" path="blackReason">
|
|
<n-input
|
|
v-model:value="blackForm.blackReason"
|
|
type="textarea"
|
|
placeholder="请输入内容"
|
|
:autosize="{ minRows: 3, maxRows: 5 }"
|
|
class="w-full"
|
|
/>
|
|
</n-form-item>
|
|
</n-form>
|
|
<div class="flex justify-center gap-4 mt-8">
|
|
<n-button
|
|
class="w-24 h-9 hover:opacity-90"
|
|
@click="showBlackModal = false"
|
|
>
|
|
取消
|
|
</n-button>
|
|
<n-button
|
|
type="primary"
|
|
class="w-24 h-9 hover:opacity-90"
|
|
:theme-overrides="{
|
|
common: {
|
|
primaryColor: '#3f7ef7',
|
|
primaryColorHover: '#3f7ef7',
|
|
},
|
|
}"
|
|
@click="handleBlack"
|
|
>
|
|
确定拉黑
|
|
</n-button>
|
|
</div>
|
|
</div>
|
|
</n-modal> -->
|
|
</div>
|
|
</template>
|