You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

381 lines
11 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div>
<card-container>
<vxe-toolbar export print ref="toolbar">
<template #buttons>
<el-button
icon="el-icon-plus"
type="primary"
size="small"
@click="isShowAdd = true"
>新增</el-button
>
<el-button
icon="el-icon-search"
type="primary"
plain
size="small"
@click="getList"
>搜索</el-button
>
</template>
</vxe-toolbar>
<vxe-table
ref="table"
stripe
style="margin-top: 10px"
:loading="loading"
keep-source
show-overflow
:column-config="{ resizable: true }"
:edit-rules="validRules"
:edit-config="{
trigger: 'manual',
mode: 'row',
showStatus: true,
isHover: true,
autoClear: false,
}"
:align="allAlign"
:data="tableData"
>
<vxe-column type="seq" width="58" align="center" />
<vxe-column
field="title"
width="200"
title="会议纪要标题"
:edit-render="{ name: 'input', attrs: { type: 'text' } }"
/>
<vxe-column
field="items"
min-width="250"
title="内容清单"
:formatter="({ cellValue }) => {
if (cellValue && cellValue instanceof Array && cellValue.length > 0) {
return cellValue.map(i => (i.type || '') + '' + (i.content || '')).join('')
}
return '无'
}"
/>
<vxe-column
field="flows"
width="200"
title="关联流程"
:formatter="({ cellValue }) => {
if (cellValue && cellValue instanceof Array && cellValue.length > 0) {
return cellValue.map(i => i.title || i.no || ('流程' + i.id)).join('、')
}
return '未关联'
}"
/>
<vxe-column field="files_details" title="附件" min-width="220" header-align="center" align="left" :edit-render="{}">
<template #default="{ row }">
<div v-if="row.files_details && row.files_details.length > 0">
<div v-for="(file, index) in row.files_details" :key="index" style="margin-bottom: 4px;">
<el-link
type="primary"
style="margin-right: 10px; cursor: pointer;"
@click="previewFile(file)"
>
<i class="el-icon-view"></i> {{ file.original_name || file.name }}
</el-link>
<el-link
type="primary"
style="cursor: pointer;"
@click="downloadFile(file)"
>
<i class="el-icon-download"></i> 下载
</el-link>
</div>
</div>
<span v-else style="color: #909399;">无附件</span>
</template>
<template #edit="{ row }">
<vxe-upload
v-model="row.files_details"
name-field="original_name"
progress-text="{percent}%"
:more-config="{ maxCount: 1, layout: 'horizontal' }"
:limit-size="uploadSize / 1024 / 1024"
:show-button-text="false"
:upload-method="({file}) => uploadMethod(file, row)"
/>
</template>
</vxe-column>
<vxe-column field="admin" title="创建人" width="100" :formatter="({ cellValue }) => (cellValue && cellValue.name) || ''" />
<vxe-column field="operate" title="操作" min-width="220" fixed="right">
<template #default="{ row }">
<template v-if="isActiveStatus(row)">
<el-button size="small" type="primary" @click="saveRowEvent(row)"
>保存</el-button
>
<el-button
size="small"
type="primary"
plain
@click="cancelRowEvent(row)"
>取消</el-button
>
</template>
<template v-else>
<el-button size="small" type="primary" @click="viewRowEvent(row)"
>查看</el-button
>
<el-button size="small" type="warning" @click="editRowEvent(row)"
>编辑</el-button
>
<el-button
size="small"
type="danger"
@click="destroyRowEvent(row)"
>删除</el-button
>
</template>
</template>
</vxe-column>
</vxe-table>
<el-pagination
style="margin-top: 10px"
:current-page.sync="select.page"
:page-sizes="[20, 30, 40, 50]"
:page-size.sync="select.page_size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="
(e) => {
select.page_size = e;
select.page = 1;
getList();
}
"
@current-change="
(e) => {
select.page = e;
getList();
}
"
/>
</card-container>
<add-meeting-minutes
ref="AddMeetingMinutes"
:type="isShowType"
:is-show.sync="isShowAdd"
@refresh="getList"
/>
</div>
</template>
<script>
import { deepCopy } from "@/utils";
import { destroy, index, save, show } from "@/api/meetingMinutes";
import AddMeetingMinutes from "./components/AddMeetingMinutes.vue";
import axios from "axios";
import { getToken } from "@/utils/auth";
import { uploadSize } from '@/settings';
import { formatFileSize } from '@/utils'
export default {
components: {
AddMeetingMinutes
},
data() {
return {
uploadSize,
isShowAdd: false,
isShowType: 'add',
loading: false,
select: {
page: 1,
page_size: 20,
show_relation: ['admin', 'flows', 'items']
},
total: 0,
allAlign: null,
tableData: [],
validRules: {},
form: {
id: "",
title: "",
meeting_time: "",
files: [],
flow_ids: [],
files_details: [],
items: []
},
};
},
computed: {
isActiveStatus() {
return function (row) {
if (this.$refs["table"]) {
return this.$refs["table"].isEditByRow(row);
}
};
},
},
created() {
this.getList();
},
mounted() {
this.bindToolbar()
},
methods: {
formatFileSize,
previewFile(file) {
// 触发预览事件
if (file.url) {
this.$bus.$emit("online-file", file.url);
} else if (file.response && file.response.data && file.response.data.url) {
this.$bus.$emit("online-file", file.response.data.url);
}
},
downloadFile(file) {
// 触发下载事件
let fileId = null;
if (file.id) {
fileId = file.id;
} else if (file.response && file.response.data && file.response.data.id) {
fileId = file.response.data.id;
}
if (fileId) {
this.$bus.$emit("online-download", fileId);
}
},
uploadMethod(file, row) {
const formData = new FormData()
formData.append('file', file)
window.$_uploading = true
return axios.post(process.env.VUE_APP_UPLOAD_API, formData, {
headers: {
Authorization: `Bearer ${getToken()}`,
}
}).then((response) => {
window.$_uploading = false
if (response.status === 200 && !response.data.code) {
if (!(row.files_details instanceof Array)) {
row.files_details = []
}
row.files_details.push({
response: response.data.data,
name: response.data.data.original_name,
url: response.data.data.url
})
} else {
this.$message.error("上传失败")
}
}).catch(err => {
window.$_uploading = false
})
},
bindToolbar() {
this.$nextTick(() => {
if (this.$refs["table"] && this.$refs["toolbar"]) {
this.$refs["table"].connect(this.$refs["toolbar"]);
}
});
},
editRowEvent(row) {
this.isShowType = 'edit'
this.$refs['AddMeetingMinutes'].getDetail(row)
this.isShowAdd = true
},
viewRowEvent(row) {
this.isShowType = 'view'
this.$refs['AddMeetingMinutes'].getDetail(row)
this.isShowAdd = true
},
cancelRowEvent(row) {
if (this.$refs["table"]) {
this.$refs["table"].clearEdit().then(() => {
// 还原行数据
this.$refs["table"].revertData(row);
});
}
},
async getList() {
this.loading = true;
try {
const res = await index(this.select);
this.tableData = res.data;
this.total = res.total;
this.loading = false;
} catch (err) {
console.error(err);
this.loading = false;
}
},
async saveRowEvent(row) {
if (window.$_uploading) {
this.$message.warning("文件正在上传中")
return
}
try {
const errMap = await this.$refs["table"].validate();
if (errMap) {
throw new Error(errMap);
}
await this.$confirm("确认保存?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
});
await this.$refs["table"].clearEdit();
const form = deepCopy(this.form);
for (const key in form) {
form[key] = row[key];
}
this.loading = true;
form['files'] = (row.files_details && row.files_details instanceof Array)
? row.files_details.map(i => (i.response && i.response.id) || i.id).filter(i => !!i)
: []
await save(form);
await this.getList();
this.loading = false;
this.$message.success("保存成功");
} catch (err) {
this.loading = false;
}
},
async destroyRowEvent(row) {
try {
await this.$confirm("确认删除?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
});
this.loading = true;
if (row.id) {
await destroy({
id: row.id,
});
await this.getList();
this.$message.success("删除成功");
} else {
this.tableData.splice(
this.tableData.findIndex((i) => i._X_ROW_KEY === row._X_ROW_KEY),
1
);
}
this.loading = false;
} catch (err) {
this.loading = false;
}
},
},
};
</script>
<style scoped lang="scss">
.total {
color: #666;
text-align: right;
line-height: 3;
}
::v-deep .el-tag + .el-tag {
margin-left: 4px;
}
</style>