2024-08-08 15:17:44 +08:00

267 lines
9.3 KiB
Vue

<!--列表式密码组件-->
<script setup lang="ts">
import {Password, Sort} from "@/types";
import {usePasswordStore} from "@/stores/PasswordStore.ts";
import {copyText, formatterDate, getBgColor, getPasswordLabelNames, getPasswordStrength, getPasswordStrengthColor, getPasswordStrengthTip, isUrl, sharePassword} from "@/utils/global.ts";
import {useRefStore} from "@/stores/RefStore.ts";
import {useSettingStore} from "@/stores/SettingStore.ts";
import {CSSProperties} from "vue";
const passwordStore = usePasswordStore()
const refStore = useRefStore()
const settingStore = useSettingStore()
// 查看密码的id
const showPasswordId = ref(0)
// 查看密码
const showLongPassword = (password: any) => {
console.log('table 查看密码:', password.id)
if (password.password.length > 40) {
console.log('table 查看密码 长度大于40')
// 长度大于40使用弹框展示
refStore.showPasswordRef.showPassword(password)
showPasswordId.value = 0
} else {
showPasswordId.value = password.id
}
}
// 删除密码
const deletePassword = (password: Password) => {
console.log('table 删除密码:', password.id)
// 询问确认删除吗?
ElMessageBox.confirm(
'确认删除“' + password.title + '”吗?',
'删除密码',
{
confirmButtonClass: 'confirm-delete-btn',
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
console.log('table 确认删除:', password.id)
passwordStore.passwordManager.deletePassword(password.id).then(resp => {
if (!resp.status){
console.log('table 删除密码异常:', resp.message)
ElNotification.error({title: '系统异常',message: resp.message})
}
})
}).catch(() => {
})
}
// 收藏密码
const favoritePassword = (password: Password) => {
if (password.favorite) {
console.log('取消收藏密码')
password.favorite = false
}else{
console.log('收藏密码')
password.favorite = true
}
password.favoriteTime = Date.now()
passwordStore.passwordManager.updatePassword(password)
}
// strength 排序
const strengthSort = (a: Password, b: Password) => {
let aSort = getPasswordStrength(a.password);
let bSort = getPasswordStrength(b.password);
// 比较值并返回排序结果
if (aSort > bSort) {
return settingStore.setting.sortOrder === Sort.ASC ? 1 : -1;
} else if (aSort < bSort) {
return settingStore.setting.sortOrder === Sort.ASC ? -1 : 1;
} else {
return 0;
}
}
const tableRowStyle = (data: { row: any, rowIndex: number }): CSSProperties => {
if (settingStore.setting.passwordColor && data.row.bgColor) {
return {'background-color': getBgColor(data.row.bgColor, '0.1')};
}else{
return {'background-color': 'rgba(0,0,0,0)'};
}
}
</script>
<template>
<EmptyList v-if="!passwordStore.visPasswordArray.length"></EmptyList>
<div class="password-card-table" v-if="passwordStore.visPasswordArray.length">
<el-table
:data="passwordStore.visPasswordArray"
ref="passwordTableRef"
height="calc(100vh - 120px)"
style="background-color: rgba(0,0,0,0);"
:header-row-style="{'background-color':'rgba(0,0,0,0)'}"
:header-cell-style="{'background-color':'rgba(0,0,0,0)'}"
:row-style="tableRowStyle"
:cell-style="{'background-color':'rgba(0,0,0,0)'}"
>
<el-table-column v-if="settingStore.setting.showStrength" prop="strength" width="30px" :sort-method="strengthSort" sortable>
<template #default="scope">
<el-tooltip :content="getPasswordStrengthTip(scope.row.password)" placement="top">
<div class="password-strength" :style="{'background-color':getPasswordStrengthColor(scope.row.password)}"></div>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="名称" min-width="130px" sortable prop="title"></el-table-column>
<el-table-column label="地址" min-width="200px" prop="address">
<template #default="scope">
<div>
<el-link v-if="isUrl(scope.row.address)" type="primary" class="address-link" :href="scope.row.address" target="_blank">
{{ scope.row.address }}
</el-link>
<el-text v-else>
{{ scope.row.address }}
</el-text>
</div>
</template>
</el-table-column>
<el-table-column label="用户名" min-width="180px" sortable prop="username">
<template #default="scope">
<div v-if="scope.row.username" class="username-div">
<div class="username-text">
{{ scope.row.username }}
</div>
<div>
<span class="iconfont icon-copy password-row-icon copy-username" @click="copyText(scope.row.username)"></span>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="密码" width="220px" prop="password">
<template #default="scope">
<div v-if="scope.row.password" class="table-password-div">
<div style="width: 150px">
<span v-if="showPasswordId === scope.row.id" class="table-password-span">{{ scope.row.password }}</span>
<span v-if="showPasswordId !== scope.row.id" class="table-password-symbol">*******</span>
</div>
<div>
<span v-if="showPasswordId === scope.row.id" class="iconfont icon-hide password-row-icon" @click="showPasswordId = 0"/>
<span v-if="showPasswordId !== scope.row.id" class="iconfont icon-show password-row-icon" @click="showLongPassword(scope.row)"/>
<span class="iconfont icon-copy password-row-icon" @click="copyText(scope.row.password)"></span>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="添加时间" min-width="150px" sortable :formatter="(row: any) => formatterDate(row.addTime,'YYYY-MM-DD HH:mm')" v-if="settingStore.setting.showTimeForTable === 'addTime'" prop="addTime"></el-table-column>
<el-table-column label="修改时间" min-width="150px" sortable :formatter="(row: any) => formatterDate(row.updateTime,'YYYY-MM-DD HH:mm')" v-if="settingStore.setting.showTimeForTable === 'updateTime'" prop="updateTime"></el-table-column>
<el-table-column label="标签" min-width="110px" v-if="settingStore.setting.showLabelForTable" prop="labels">
<template #default="scope">
<el-tag v-for="label in getPasswordLabelNames(scope.row)" class="table-label">
{{ label.name }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="备注" min-width="130px" prop="remark"></el-table-column>
<el-table-column label="操作" min-width="145px" width="150px">
<template #default="scope">
<div style="display: flex;justify-content: space-evenly;">
<el-tooltip content="分享" placement="top">
<el-link type="success" @click="sharePassword(scope.row)" :underline="false">
<span class="iconfont icon-share table-opt-icon"/>
</el-link>
</el-tooltip>
<el-tooltip content="修改" placement="top">
<el-link type="primary" @click="refStore.passwordFormRef.editPasswordForm(scope.row)" :underline="false">
<span class="iconfont icon-edit table-opt-icon"/>
</el-link>
</el-tooltip>
<el-tooltip :content="scope.row.favorite?'取消收藏':'收藏'" placement="top">
<el-link v-if="scope.row.favorite" type="primary" @click="favoritePassword(scope.row)" :underline="false">
<span class="iconfont icon-favorited table-opt-icon" style="color: #FF9700"/>
</el-link>
<el-link v-if="!scope.row.favorite" type="primary" @click="favoritePassword(scope.row)" :underline="false">
<span class="iconfont icon-collect table-opt-icon" style="color: #FF9700"/>
</el-link>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-link type="danger" @click="deletePassword(scope.row)" :underline="false">
<span class="iconfont icon-delete table-opt-icon"/>
</el-link>
</el-tooltip>
</div>
</template>
</el-table-column>
</el-table>
</div>
</template>
<style scoped>
.password-card-table {
padding: 13px;
}
.password-row-icon {
margin-left: 3px;
cursor: pointer;
padding: 5px;
border-radius: 5px;
font-size: 16px;
line-height: 34px;
height: 34px;
}
.password-row-icon:hover {
background-color: rgba(200, 200, 200, 0.3);
color: #409eff;
}
.icon-hide, .icon-show {
font-size: 20px;
position: relative;
top: 2px;
}
.password-strength {
border-radius: 50%;
width: 13px;
height: 13px;
}
.copy-username {
margin-left: 10px
}
.username-div, .table-password-div {
display: flex;
justify-content: space-between;
}
.username-text {
width: 130px
}
.table-password-span {
line-height: 36px;
word-wrap: break-word;
word-break: normal;
}
.table-password-symbol {
line-height: 36px;
}
.table-opt-icon {
font-size: 130%;
}
.table-label {
margin: 3px;
cursor: default;
}
.address-link{
max-width: 100%;
}
:deep(.address-link .el-link__inner) {
min-width: 0;
display: block;
}
</style>