Smail/fe/src/views/ListView.vue
HuangZhe ad0167f6fd
代码分离,功能优化 (#204)
* feat: 代码分离,功能优化

1. 代码迁移到 ts.
2. 分离 axios 部分代码.
3. 增加 pinia 支持,全局状态代码迁移到相对应的 store.
4. 代码格式优化, 用 === 代替 ==.
5. 代码声明更改,用 const 代替 var 声明.
6. Header 使用 Router 导航.
7. v-for 增加 key.

* fix[fe]: 移除过时的 prop 引用

* fix[fe]: 移除过时的 prop 引用

* fix[fe]: 修复 logo 上面有横线的问题

* fix[fe]: 修复 logo 上面有横线的问题

---------

Co-authored-by: zhe28 <huangze28@foxmail.com>
2024-09-23 10:24:49 +08:00

304 lines
7.8 KiB
Vue

<template>
<div style="height: 100%">
<div id="operation">
<div id="action">
<RouterLink to="/editer">+{{ lang.compose }}</RouterLink>
</div>
</div>
<div id="title">{{ groupStore.name }}</div>
<div id="action">
<el-button @click="del" size="small">{{ lang.del_btn }}</el-button>
<el-button @click="markRead" size="small">{{ lang.read_btn }}</el-button>
<el-dropdown style="margin-left: 12px;">
<el-button size="small">
{{ lang.move_btn }}
<el-icon class="el-icon--right">
<EpArrowDownBold />
</el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="move(group.id)" v-for="group in groupList" :key="group.id">{{
group.name
}}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
<div id="table">
<el-table ref="taskTableDataRef" :data="data" :show-header="true"
:border="false" @row-click="rowClick" :row-style="rowStyle">
<el-table-column type="selection" width="30"/>
<el-table-column prop="is_read" label="" width="50">
<template #default="scope">
<div>
<span v-if="!scope.row.is_read">
{{ lang.new }}
</span>
<span style="font-weight: 900;color: #FF0000;" v-if="scope.row.dangerous">
<el-tooltip effect="dark" :content="lang.dangerous" placement="top-start">
!
</el-tooltip>
</span>
<span style="font-weight: 900;color: #FF0000;" v-if="scope.row.error !== ''">
<el-tooltip effect="dark" :content="scope.row.error" placement="top-start">
!
</el-tooltip>
</span>
</div>
</template>
</el-table-column>
<el-table-column prop="title" :label="lang.sender" width="150">
<template #default="scope">
<el-tooltip class="box-item" effect="dark" :content="scope.row.sender.EmailAddress" placement="top">
<el-tag size="small" type="info">
{{ scope.row.sender.Name !== '' ? scope.row.sender.Name : scope.row.sender.EmailAddress }}
</el-tag>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="title" :label="lang.to" width="150">
<template #default="scope">
<el-tooltip v-for="toInfo in scope.row.to" :key="toInfo" class="box-item" effect="dark" :content="toInfo.EmailAddress"
placement="top">
<el-tag size="small" type="info">{{ toInfo.Name !== '' ? toInfo.Name : toInfo.EmailAddress }}</el-tag>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="desc" :label="lang.title">
<template #default="scope">
<div v-if="scope.row.is_read">{{ scope.row.title }}</div>
<div v-else style="font-weight:bolder;">{{ scope.row.title }}</div>
<div style="font-size: 12px;height: 24px;">{{ scope.row.desc }}</div>
</template>
</el-table-column>
<el-table-column prop="datetime" :label="lang.date" width="180">
<template #default="scope">
<span v-if="scope.row.is_read">{{ scope.row.datetime }}</span>
<span v-else style="font-weight:bolder;">{{ scope.row.datetime }}</span>
</template>
</el-table-column>
</el-table>
</div>
<div id="pagination">
<el-pagination background layout="prev, pager, next" :page-count="totalPage" @current-change="pageChange"/>
</div>
</div>
</template>
<script setup>
import {EpArrowDownBold} from "vue-icons-plus/ep";
import {RouterLink, useRouter} from 'vue-router'
import {ref, watch} from 'vue'
import useGroupStore from '../stores/group'
import lang from '../i18n/i18n';
import {http} from "@/utils/axios";
import {ElMessage, ElMessageBox} from "element-plus";
const router = useRouter();
const groupStore = useGroupStore()
const groupList = ref([])
const taskTableDataRef = ref(null)
let tag = groupStore.tag;
if (tag === "") {
tag = '{"type":0,"status":-1}'
}
watch(groupStore, async (newV) => {
tag = newV.tag;
if (tag === "") {
tag = '{"type":0,"status":-1}'
}
data.value = []
http.post("/api/email/list", {tag: tag, page_size: 10}).then(res => {
data.value = res.data.list
totalPage.value = res.data.total_page
})
})
const data = ref([])
const totalPage = ref(0)
const updateList = function () {
http.post("/api/email/list", {tag: tag, page_size: 10}).then(res => {
data.value = res.data.list
totalPage.value = res.data.total_page
})
}
const updateGroupList = function () {
http.post("/api/group/list").then(res => {
groupList.value = res.data
})
}
updateList()
updateGroupList()
const rowClick = function (row) {
router.push("/detail/" + row.id)
}
const markRead = function () {
let rows = taskTableDataRef.value?.getSelectionRows()
let ids = []
rows.forEach(element => {
ids.push(element.id)
});
http.post("/api/email/read", {"ids": ids}).then(res => {
if (res.errorNo === 0) {
updateList()
} else {
ElMessage({
type: 'error',
message: res.errorMsg,
})
}
})
}
const move = function (group_id) {
let rows = taskTableDataRef.value?.getSelectionRows()
let ids = []
rows.forEach(element => {
ids.push(element.id)
});
ElMessageBox.confirm(
lang.move_email_confirm,
'Warning',
{
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning',
}
)
.then(() => {
http.post("/api/email/move", {"group_id": group_id, "ids": ids}).then(res => {
if (res.errorNo === 0) {
updateList()
ElMessage({
type: 'success',
message: 'Move completed',
})
} else {
ElMessage({
type: 'error',
message: res.errorMsg,
})
}
})
})
}
const del = function () {
let rows = taskTableDataRef.value?.getSelectionRows()
let ids = []
rows.forEach(element => {
ids.push(element.id)
});
let groupTag = JSON.parse(tag)
ElMessageBox.confirm(
lang.del_email_confirm,
'Warning',
{
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning',
}
)
.then(() => {
http.post("/api/email/del", {"ids": ids, "forcedDel": groupTag.status === 3}).then(res => {
if (res.errorNo === 0) {
updateList()
ElMessage({
type: 'success',
message: 'Delete completed',
})
} else {
ElMessage({
type: 'error',
message: res.errorMsg,
})
}
})
})
}
const rowStyle = function () {
return {'cursor': 'pointer'}
}
const pageChange = function (p) {
http.post("/api/email/list", {tag: tag, page_size: 10, current_page: p}).then(res => {
data.value = res.data.list
})
}
</script>
<style scoped>
#action {
display: flex;
flex-direction: row;
}
#action a,
a:visited {
color: #000000;
text-decoration: none;
}
#operation {
display: flex;
height: 40px;
background-color: rgb(236, 244, 251);
}
#title {
margin-top: 10px;
font-size: 23px;
text-align: left;
padding-left: 20px;
}
#table {
text-align: left;
width: 100%;
padding-left: 20px;
}
#pagination {
padding-top: 30px;
display: flex;
justify-content: center;
/* 水平居中 */
width: 100%;
}
</style>