附件完成

dev
rdpnr_hemingxia 2025-04-23 15:32:58 +08:00
parent bc1c74ce55
commit b1251e3bc5
9 changed files with 684 additions and 59 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

View File

@ -15,6 +15,22 @@
/> />
</div> </div>
<div class="user-list"> <div class="user-list">
<div class="flex-row aic jcfe mb10" style="gap: 10px">
<el-input
v-model="searchForm.nickName"
style="width: 300px"
placeholder="输入名称"
/>
<div>
<el-button type="primary" size="medium" @click="fetchUserList"
>查询</el-button
>
<el-button type="primary" size="medium" @click="resetTable"
>重置</el-button
>
</div>
</div>
<CustomTable <CustomTable
ref="customTableRef" ref="customTableRef"
:columns="columns" :columns="columns"
@ -101,6 +117,10 @@ export default {
type: Function, type: Function,
default: () => true, default: () => true,
}, },
userIdList: {
type: Array,
default: () => [],
},
}, },
data() { data() {
return { return {
@ -133,6 +153,9 @@ export default {
userData: [], userData: [],
isInternalChange: false, isInternalChange: false,
selectAllData: [], selectAllData: [],
searchForm: {
nickName: "",
},
}; };
}, },
emits: ["close", "confirm"], emits: ["close", "confirm"],
@ -196,10 +219,9 @@ export default {
} }
}, },
selectAll(arr) { selectAll(arr) {
let filterArr = this.selectAllData.filter((ele) => let filterArr = this.selectAllData.filter(
!arr.some((item) => item.userId == ele.userId) (ele) => !arr.some((item) => item.userId == ele.userId)
); );
console.log(filterArr,11);
arr.forEach((ele) => { arr.forEach((ele) => {
if ( if (
@ -208,20 +230,29 @@ export default {
this.selectRow({ row: ele }); this.selectRow({ row: ele });
}); });
filterArr.forEach((ele) => { filterArr.forEach((ele) => {
this.selectRow({ row: ele }); this.selectRow({ row: ele });
}); });
}, },
fetchUserList: async function () { fetchUserList: async function () {
const response = await systemApi.getUserList({ const response = await systemApi.getUserList({
pageNum: this.currentPage, pageNum: this.currentPage,
pageSize: this.pageSize, pageSize: this.pageSize,
deptId: this.currentDepartment, deptId: this.currentDepartment,
...this.searchForm,
userIdList:this.userIdList,
}); });
this.userData = response.rows; this.userData = response.rows;
this.total = response.total; this.total = response.total;
if (!this.multiSelect) {
this.userData.forEach((ele) => {
if (ele.userId == this.selectedUsers[0]?.userId)
this.$refs.customTableRef?.setCurrentRow(ele);
});
}
},
resetTable() {
this.searchForm.nickName = "";
this.fetchUserList();
}, },
fetchTreeData: async function () { fetchTreeData: async function () {
const response = await systemApi.getDeptTree(); const response = await systemApi.getDeptTree();
@ -305,6 +336,13 @@ export default {
immediate: true, immediate: true,
deep: true, deep: true,
}, },
userIdList: {
handler(newVal) {
this.fetchUserList();
},
immediate: true,
deep: true,
},
}, },
mounted() { mounted() {
this.fetchTreeData(); this.fetchTreeData();

View File

@ -1,6 +1,6 @@
import request from '@/utils/request' import request from '@/utils/request'
// 登录板块api // 公用板块
// 项目板块 // 项目板块
export const projectApi = { export const projectApi = {
@ -92,6 +92,7 @@ export const workLogApi = {
method: 'delete', method: 'delete',
}), }),
} }
// 项目看板 // 项目看板
@ -133,6 +134,18 @@ export const systemApi = {
url: '/system/user/deptTree', url: '/system/user/deptTree',
method: 'get', method: 'get',
}), }),
fileUpload: '/common/upload',
downFile: (data) => request({
url: '/common/download',
method: 'get',
params: data,
}),
delFile: (id) => request({
url: `/business/project/file/${id}`,
method: 'delete',
}),
} }
// 任务考核板块 // 任务考核板块
@ -237,6 +250,10 @@ export const demandApi = {
url: `/demand/${data}`, url: `/demand/${data}`,
method: 'delete', method: 'delete',
}), }),
getDemandDetail:(id) => request({
url: `/demand/${id}`,
method: 'get',
}),
delDemandBatch: (data) => request({ delDemandBatch: (data) => request({
url: `/demand/remove/batch/${data}`, url: `/demand/remove/batch/${data}`,
method: 'delete', method: 'delete',

View File

@ -74,6 +74,7 @@
style="width: 100%" style="width: 100%"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
class="tableBox" class="tableBox"
:cell-class-name="setRowClass"
> >
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
<el-table-column label="序号" width="70" type="index" /> <el-table-column label="序号" width="70" type="index" />
@ -223,11 +224,12 @@
:currentSelectedUser="currentSelectedUser" :currentSelectedUser="currentSelectedUser"
@confirm="handleUserConfirm" @confirm="handleUserConfirm"
@close="handleUserClose" @close="handleUserClose"
:userIdList="projectUserList"
/> />
<el-dialog <el-dialog
:title="!editData.id ? '新建需求' : '修改需求'" :title="!editData.id ? '新建需求' : '修改需求'"
:visible.sync="dialogVisibleAdd" :visible.sync="dialogVisibleAdd"
width="780px" width="660px"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<el-form <el-form
@ -237,6 +239,7 @@
label-width="80px" label-width="80px"
class="addForm" class="addForm"
ref="ruleForm" ref="ruleForm"
v-loading="fileLoading"
> >
<el-form-item label="标题" class="longItem" prop="title"> <el-form-item label="标题" class="longItem" prop="title">
<el-input v-model="editData.title"></el-input> <el-input v-model="editData.title"></el-input>
@ -321,7 +324,7 @@
v-model="editData.createTime" v-model="editData.createTime"
type="date" type="date"
placeholder="选择日期" placeholder="选择日期"
style="width: 240px" style="width: 200px"
value-format="yyyy-MM-dd 00:00:00" value-format="yyyy-MM-dd 00:00:00"
:picker-options="{ :picker-options="{
disabledDate: setDateRange, disabledDate: setDateRange,
@ -335,13 +338,53 @@
type="date" type="date"
placeholder="选择日期" placeholder="选择日期"
value-format="yyyy-MM-dd 23:59:59" value-format="yyyy-MM-dd 23:59:59"
style="width: 240px" style="width: 200px"
:picker-options="{ :picker-options="{
disabledDate: setDateRange, disabledDate: setDateRange,
}" }"
> >
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="附件" class="longItem" prop="endTime">
<div>
<el-upload
class="upload-demo"
ref="upload"
:action="fileUpload"
:show-file-list="false"
:auto-upload="true"
:multiple="true"
:before-upload="beforeUpload"
:on-success="successUpload"
:headers="{
Authorization: 'Bearer ' + token,
}"
:data="{}"
>
<div class="flex-row aic" style="gap: 10px;margin-bottom: 10px;">
<el-button slot="trigger" size="small" type="default" style="width: 200px;color: #333;font-weight: 500;"
>上传附件</el-button
>
<div slot="tip" style="color: #999999;font-size: 12px;">单个附件限制100M</div>
</div>
</el-upload>
<div class="fileBox">
<div
v-for="(item, index) in editData.fileList"
class="fileRow flex-row jcsb aic"
:key="index"
>
<div class="flex-row aic fileItem">
<img class="" :src="filePng" v-if="getFileType(item.fileName)=='file'"> </img>
<img class="" :src="imagePng" v-else-if="getFileType(item.fileName)=='image'"> </img>
<img class="" :src="zipPng" v-else-if="getFileType(item.fileName)=='zip'"> </img>
<div @click="downFile(item.fileUrl)">{{ item.fileName }}</div>
</div>
<div class="del" @click="delFile(item)">×</div>
</div>
</div>
</div>
</el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button @click="dialogVisibleAdd = false">取消</el-button> <el-button @click="dialogVisibleAdd = false">取消</el-button>
@ -352,8 +395,12 @@
</template> </template>
<script> <script>
import { demandApi, systemApi } from "@/utils/api"; import { demandApi, systemApi, projectApi } from "@/utils/api";
import SelectUser from "@/components/SelectUser.vue"; import SelectUser from "@/components/SelectUser.vue";
import { getToken } from "@/utils/auth";
import filePng from "@/assets/images/file.png";
import zipPng from "@/assets/images/zip.png";
import imagePng from "@/assets/images/image.png";
export default { export default {
name: "MainContentTable", name: "MainContentTable",
@ -414,7 +461,10 @@ export default {
endTime: "", endTime: "",
priority: "", priority: "",
projectId: "", projectId: "",
fileList: [],
}, },
token: getToken(),
fileUpload: systemApi.fileUpload,
rules: { rules: {
title: [ title: [
{ required: true, message: "请输入标题", trigger: "change" }, { required: true, message: "请输入标题", trigger: "change" },
@ -463,6 +513,11 @@ export default {
value: index + 1, value: index + 1,
label: index + 1 + "天", label: index + 1 + "天",
})), })),
projectUserList: [],
fileLoading: false,
filePng,
zipPng,
imagePng,
}; };
}, },
watch: { watch: {
@ -484,6 +539,7 @@ export default {
}, },
projectId(newVal) { projectId(newVal) {
this.editData.projectId = newVal; this.editData.projectId = newVal;
this.getProjectUser();
}, },
projectName(newVal) { projectName(newVal) {
this.editData.projectName = newVal; this.editData.projectName = newVal;
@ -521,6 +577,7 @@ export default {
endTime: "", endTime: "",
priority: "", priority: "",
projectId: "", projectId: "",
fileList: [],
}; };
this.$nextTick(() => { this.$nextTick(() => {
if (this.$refs.ruleForm) { if (this.$refs.ruleForm) {
@ -534,19 +591,20 @@ export default {
this.editData.projectName = this.projectName; this.editData.projectName = this.projectName;
}, },
handleEdit(row) { handleEdit(row) {
// if (row.demandStatus == 4) {
// this.$message({
// type: "warning",
// message: "!",
// });
// return;
// }
this.editData = row; this.editData = row;
this.editData.projectId = this.projectId; this.editData.projectId = this.projectId;
this.editData.projectName = this.projectName; this.editData.projectName = this.projectName;
this.dialogVisibleAdd = true; this.dialogVisibleAdd = true;
this.getDemandDetail(row);
// //
}, },
async getDemandDetail(row) {
const res = await demandApi.getDemandDetail(row.id);
this.editData.fileList = res.data.fileList;
},
downFile(url) {
window.open(url);
},
handleDelete(row) { handleDelete(row) {
// //
this.$confirm("此操作将永久删除该需求, 是否继续?", "提示", { this.$confirm("此操作将永久删除该需求, 是否继续?", "提示", {
@ -733,31 +791,6 @@ export default {
}); });
return; return;
} }
// if (this.editData.demandStatus == 4) {
// this.$confirm("使, ?", "", {
// confirmButtonText: "",
// cancelButtonText: "",
// type: "warning",
// }).then(() => {
// if (this.editData.id) {
// demandApi.eidtDemand(this.editData).then((res) => {
// this.$message({
// message: "",
// type: "success",
// });
// this.resetList();
// });
// } else {
// demandApi.addDemand(this.editData).then((res) => {
// this.$message({
// message: "",
// type: "success",
// });
// this.resetList();
// });
// }
// });
// } else {
if (this.editData.id) { if (this.editData.id) {
demandApi.eidtDemand(this.editData).then((res) => { demandApi.eidtDemand(this.editData).then((res) => {
this.$message({ this.$message({
@ -853,6 +886,100 @@ export default {
return false; return false;
} }
}, },
//
async getProjectUser() {
const res1 = await projectApi.getProjectDetail(this.projectId);
const res2 = await projectApi.getProjectUser(this.projectId);
this.projectUserList = [
res1.data.projectLeader,
...res2.data?.map((ele) => ele.userId),
];
},
setRowClass({ row }) {
if (row.demandStatus == 4) {
return "disabled";
}
},
beforeUpload(file) {
this.fileLoading = true;
if (file.size > 1024 * 1024 * 100) {
this.fileLoading = false;
this.$message({
type: "warning",
message: "单个文件不能大于100M!",
});
return false;
}
},
successUpload(res,file,fileList) {
if(!fileList.filter((ele)=>ele.percentage!=100).length){
this.fileLoading = false;
}
if (res.code == 200) {
this.editData.fileList.push({
fileName: res.originalFilename, //
filePath: res.filePath, //
fileNewName: res.newFileName, //
fileUrl: res.url,
});
} else {
this.$message({
type: "error",
message: res.msg,
});
}
},
delFile(row) {
if (row.id) {
this.$confirm("此操作将永久删除文件, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
systemApi.delFile(row.id).then((res) => {
this.editData.fileList = this.editData.fileList.filter(
(ele) => ele.fileNewName != row.fileNewName
);
this.$message({
type:'success',
message: "删除成功!"
})
});
});
} else {
this.editData.fileList = this.editData.fileList.filter(
(ele) => ele.fileNewName != row.fileNewName
);
this.$message({
type:'success',
message: "删除成功!"
})
}
},
getFileType(name){
var data={
jpg: 'image',
jpeg: 'image',
png: 'image',
gif: 'image',
bmp: 'image',
tiff: 'image',
svg: 'image',
pdf: 'file',
doc: 'file',
docx: 'file',
xls: 'file',
xlsx: 'file',
txt: 'file',
ppt: 'file',
zip: 'zip',
rar: 'zip',
tar: 'zip',
targz: 'zip',
}
return data[name.split('.')[1]]||'file'
}
}, },
created() { created() {
this.getDictData(); this.getDictData();
@ -926,11 +1053,16 @@ export default {
background-color: #50b6aa !important; background-color: #50b6aa !important;
} }
} }
::v-deep .status-tag.closed .el-radio__inner, ::v-deep .status-tag.closed .el-radio__inner {
::v-deep .status-tag.wait .el-radio__inner { border-color: #ccc !important;
border-color: #999999 !important;
&::after { &::after {
background-color: #999999 !important; background-color: #ccc !important;
}
}
::v-deep .status-tag.wait .el-radio__inner {
border-color: #999 !important;
&::after {
background-color: #999 !important;
} }
} }
::v-deep .status-tag.pending .el-radio__label { ::v-deep .status-tag.pending .el-radio__label {
@ -948,12 +1080,13 @@ export default {
// background-color: #e6f7f5; // background-color: #e6f7f5;
} }
::v-deep .status-tag.closed .el-radio__label,
::v-deep .status-tag.wait .el-radio__label { ::v-deep .status-tag.wait .el-radio__label {
color: #999999 !important; color: #999 !important;
// background-color: #f5f5f5; // background-color: #f5f5f5;
} }
::v-deep .status-tag.closed .el-radio__label {
color: #ccc !important;
}
.pagination { .pagination {
margin-top: 20px; margin-top: 20px;
display: flex; display: flex;
@ -966,6 +1099,12 @@ export default {
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
} }
::v-deep .disabled.el-table__cell {
color: #ccc;
.el-dropdown-link {
color: #ccc;
}
}
::v-deep .el-button { ::v-deep .el-button {
border-radius: 4px; border-radius: 4px;
@ -1009,7 +1148,7 @@ export default {
::v-deep .addForm { ::v-deep .addForm {
.el-input__inner { .el-input__inner {
// width: 100%; // width: 100%;
width: 240px; width: 200px;
} }
.el-form-item { .el-form-item {
width: 48%; width: 48%;
@ -1068,4 +1207,28 @@ export default {
font-weight: 600; font-weight: 600;
color: #333; color: #333;
} }
.fileRow {
height: 38px;
padding: 0 10px;
border: 1px solid #ccc;
border-radius: 5px;
margin-bottom: 10px;
.del {
font-size: 16px;
cursor: pointer;
}
img{
height: 18px;
}
}
.fileItem{
gap: 10px;
cursor: pointer;
}
.fileBox{
max-height: 200px;
overflow: auto;
padding-right: 10px;
}
</style> </style>

View File

@ -1,5 +1,7 @@
<template> <template>
<div class="project-management"> <div class="project-management"
v-loading="fileLoading"
>
<el-form <el-form
ref="formRef" ref="formRef"
:model="formData" :model="formData"
@ -115,6 +117,50 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="24">
<el-col :span="24">
<el-form-item label="附件" prop="fileList">
<div>
<el-upload
class="upload-demo"
ref="upload"
:action="fileUpload"
:show-file-list="false"
:auto-upload="true"
:multiple="true"
:before-upload="beforeUpload"
:on-success="successUpload"
:headers="{
Authorization: 'Bearer ' + token,
}"
:data="{}"
>
<div class="flex-row aic" style="gap: 10px;margin-bottom: 10px;">
<el-button slot="trigger" size="small" type="default" style="width: 200px;color: #333;font-weight: 500;"
>上传附件</el-button
>
<div slot="tip" style="color: #999999;font-size: 12px;">单个附件限制100M</div>
</div>
</el-upload>
<div class="fileBox">
<div
v-for="(item, index) in formData.fileList"
class="fileRow flex-row jcsb aic"
:key="index"
>
<div class="flex-row aic fileItem">
<img class="" :src="filePng" v-if="getFileType(item.fileName)=='file'"> </img>
<img class="" :src="imagePng" v-else-if="getFileType(item.fileName)=='image'"> </img>
<img class="" :src="zipPng" v-else-if="getFileType(item.fileName)=='zip'"> </img>
<div @click="downFile(item.fileUrl)">{{ item.fileName }}</div>
</div>
<div class="del" @click="delFile(item)">×</div>
</div>
</div>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<div class="form-actions jcc" v-show="!isEditing"> <div class="form-actions jcc" v-show="!isEditing">
<el-button <el-button
@ -263,6 +309,10 @@
import CustomTable from "@/components/CustomTable.vue"; import CustomTable from "@/components/CustomTable.vue";
import SelectUser from "@/components/SelectUser.vue"; import SelectUser from "@/components/SelectUser.vue";
import { projectApi, systemApi } from "@/utils/api"; import { projectApi, systemApi } from "@/utils/api";
import filePng from "@/assets/images/file.png";
import zipPng from "@/assets/images/zip.png";
import imagePng from "@/assets/images/image.png";
import { getToken } from "@/utils/auth";
export default { export default {
components: { components: {
@ -288,9 +338,12 @@ export default {
budgetDate: 0, budgetDate: 0,
state: 0, state: 0,
dataState: 0, dataState: 0,
fileList:[]
}, },
postOptions: [], postOptions: [],
statusList: [], statusList: [],
fileUpload: systemApi.fileUpload,
columns: [ columns: [
{ prop: "userName", label: "姓名" }, { prop: "userName", label: "姓名" },
{ prop: "post", label: "项目职位" }, { prop: "post", label: "项目职位" },
@ -298,6 +351,8 @@ export default {
{ prop: "operation", label: "操作", width: "250px" }, { prop: "operation", label: "操作", width: "250px" },
], ],
tableData: [], tableData: [],
fileLoading: false,
currentEditingRow: {}, currentEditingRow: {},
currentSelectedUser: [], currentSelectedUser: [],
projectManagerSelectedUser: [], projectManagerSelectedUser: [],
@ -322,7 +377,15 @@ export default {
budgetDate: [ budgetDate: [
{ required: true, message: "预算天数为必填", trigger: "blur" }, { required: true, message: "预算天数为必填", trigger: "blur" },
], ],
fileList: [
{ required: true, message: "预算天数为必填", trigger: "blur" },
],
}, },
filePng,
zipPng,
imagePng,
token: getToken(),
}; };
}, },
watch: { watch: {
@ -571,6 +634,7 @@ export default {
projectState, projectState,
budgetDate, budgetDate,
state, state,
fileList
} = response.data; } = response.data;
let startDate = projectData.startDate.split(" ")[0]; let startDate = projectData.startDate.split(" ")[0];
let endDate = projectData.endDate.split(" ")[0]; let endDate = projectData.endDate.split(" ")[0];
@ -585,6 +649,7 @@ export default {
endDate, endDate,
budgetDate, budgetDate,
state, state,
fileList
}; };
this.updateProjectState(); // this.updateProjectState(); //
} catch (error) { } catch (error) {
@ -627,6 +692,89 @@ export default {
this.$modal.msgError("更新用户信息失败"); this.$modal.msgError("更新用户信息失败");
} }
}, },
beforeUpload(file) {
this.fileLoading = true;
if (file.size > 1024 * 1024 * 100) {
this.fileLoading = false;
this.$message({
type: "warning",
message: "单个文件不能大于100M!",
});
return false;
}
},
successUpload(res,file,fileList) {
if(!fileList.filter((ele)=>ele.percentage!=100).length){
this.fileLoading = false;
}
if (res.code == 200) {
this.formData.fileList.push({
fileName: res.originalFilename, //
filePath: res.filePath, //
fileNewName: res.newFileName, //
fileUrl: res.url,
});
} else {
this.$message({
type: "error",
message: res.msg,
});
}
},
delFile(row) {
if (row.id) {
this.$confirm("此操作将永久删除文件, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
systemApi.delFile(row.id).then((res) => {
this.formData.fileList = this.formData.fileList.filter(
(ele) => ele.fileNewName != row.fileNewName
);
this.$message({
type:'success',
message: "删除成功!"
})
});
});
} else {
this.formData.fileList = this.formData.fileList.filter(
(ele) => ele.fileNewName != row.fileNewName
);
this.$message({
type:'success',
message: "删除成功!"
})
}
},
getFileType(name){
var data={
jpg: 'image',
jpeg: 'image',
png: 'image',
gif: 'image',
bmp: 'image',
tiff: 'image',
svg: 'image',
pdf: 'file',
doc: 'file',
docx: 'file',
xls: 'file',
xlsx: 'file',
txt: 'file',
ppt: 'file',
zip: 'zip',
rar: 'zip',
tar: 'zip',
targz: 'zip',
}
return data[name.split('.')[1]]||'file'
},
downFile(url) {
window.open(url);
},
}, },
mounted() { mounted() {
const projectId = this.$route.params.id || this.$route.query.id; const projectId = this.$route.params.id || this.$route.query.id;
@ -779,4 +927,30 @@ export default {
height: 64px; height: 64px;
margin-bottom: 16px; margin-bottom: 16px;
} }
.fileRow {
height: 38px;
padding: 0 10px;
border: 1px solid #ccc;
border-radius: 5px;
margin-bottom: 10px;
img{
height: 18px;
}
.del {
font-size: 16px;
cursor: pointer;
}
}
.fileItem{
gap: 10px;
cursor: pointer;
}
.fileBox{
max-height: 200px;
overflow: auto;
padding-right: 10px;
max-width: 90%;
}
</style> </style>

View File

@ -37,6 +37,12 @@
hasLog: calendarList.filter( hasLog: calendarList.filter(
(ele) => ele.date == data.day + ' 00:00:00' && ele.state != -1 (ele) => ele.date == data.day + ' 00:00:00' && ele.state != -1
).length, ).length,
timeout: isTimeOut(
data.day,
calendarList.find(
(ele) => ele.date == data.day + ' 00:00:00' && ele.state == -1
)
),
}" }"
> >
{{ data.day.split("-")[2] }} {{ data.day.split("-")[2] }}
@ -104,6 +110,15 @@ export default {
isOverDay(data) { isOverDay(data) {
return new Date(data).getTime() > new Date(this.nowDay).getTime(); return new Date(data).getTime() > new Date(this.nowDay).getTime();
}, },
isTimeOut(data, hasDay) {
if (
hasDay &&
new Date(data).getTime() <
new Date(this.moment().format(`YYYY-MM-DD 00:00:00`)).getTime()
) {
return true;
}
},
getLogMonth() { getLogMonth() {
if (this.$route.query.userId) { if (this.$route.query.userId) {
this.userId = this.$route.query.userId; this.userId = this.$route.query.userId;
@ -181,6 +196,11 @@ export default {
border-radius: 50%; border-radius: 50%;
color: #fff; color: #fff;
} }
.timeout {
background: #f7c940;
border-radius: 50%;
color: #fff;
}
td { td {
border: none; border: none;
padding: 10px 0; padding: 10px 0;

View File

@ -160,12 +160,16 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="120"> <el-table-column label="操作" width="200">
<template #default="scope"> <template #default="scope">
<div v-show="!disableTable"> <div v-show="!disableTable">
<el-button type="text" @click="handleFile(scope.row)">
附件详情
</el-button>
<el-button type="text" @click="handleEdit(scope.row)"> <el-button type="text" @click="handleEdit(scope.row)">
{{ scope.row.loggerId && !scope.row.edit ? "编辑" : "确认" }} {{ scope.row.loggerId && !scope.row.edit ? "编辑" : "确认" }}
</el-button> </el-button>
<el-button <el-button
type="text" type="text"
@click="handleDelete(scope.row, scope.$index)" @click="handleDelete(scope.row, scope.$index)"
@ -177,12 +181,96 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-dialog
title="附件"
:visible.sync="dialogVisibleFile"
width="780px"
:close-on-click-modal="false"
>
<div v-loading="fileLoading">
<div>
<el-upload
class="upload-demo"
ref="upload"
:action="fileUpload"
:show-file-list="false"
:auto-upload="true"
:multiple="true"
:before-upload="beforeUpload"
:on-success="successUpload"
:headers="{
Authorization: 'Bearer ' + token,
}"
:data="{}"
>
<div class="flex-row aic" style="gap: 10px; margin-bottom: 10px">
<el-button
slot="trigger"
size="small"
type="default"
style="width: 80px; color: #333; font-weight: 500"
>上传附件</el-button
>
<div slot="tip" style="color: #999999; font-size: 12px">
单个附件限制100M
</div>
</div>
</el-upload>
</div>
<el-table :data="fileList" style="width: 100%" class="tableBox">
<el-table-column label="名称" prop="fileNewName">
<template #default="scope">
<div class="flex-row aic fileBox" style="gap: 10px;">
<img class="" :src="filePng" v-if="getFileType(scope.row.fileNewName)=='file'"> </img>
<img class="" :src="imagePng" v-else-if="getFileType(scope.row.fileNewName)=='image'"> </img>
<img class="" :src="zipPng" v-else-if="getFileType(scope.row.fileNewName)=='zip'"> </img>
<div class="downFileBox" @click="downFile(scope.row.fileUrl)">
{{ scope.row.fileNewName }}
</div>
</div>
</template>
</el-table-column>
<el-table-column label="类型" prop="fileName">
<template #default="scope">
<div>
{{ scope.row.fileNewName.split(".")[1] }}
</div>
</template>
</el-table-column>
<el-table-column label="上传时间" prop="createTime">
<template #default="scope">
<div>
{{
scope.row.createTime || moment().format("YYYY-MM-DD HH:mm:ss")
}}
</div>
</template>
</el-table-column>
<el-table-column label="操作" width="120">
<template #default="scope">
<div>
<el-button type="text" @click="delFile(scope.row)">
删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div slot="footer" class="dialog-footer">
<el-button @click="cancalFile"></el-button>
<el-button type="primary" @click="saveFile"></el-button>
</div>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { demandApi, workLogApi, projectApi } from "@/utils/api"; import { demandApi, workLogApi, projectApi, systemApi } from "@/utils/api";
import { getToken } from "@/utils/auth";
import filePng from "@/assets/images/file.png";
import zipPng from "@/assets/images/zip.png";
import imagePng from "@/assets/images/image.png";
export default { export default {
name: "RightTable", name: "RightTable",
props: { props: {
@ -207,6 +295,15 @@ export default {
hasTimeLong: 0, hasTimeLong: 0,
workTimeList: [], workTimeList: [],
oldContent: "", oldContent: "",
dialogVisibleFile: false,
fileList: [],
checkRow: {},
fileUpload: systemApi.fileUpload,
token: getToken(),
fileLoading: false,
filePng,
zipPng,
imagePng,
}; };
}, },
methods: { methods: {
@ -214,7 +311,7 @@ export default {
if (this.$route.query.userId) { if (this.$route.query.userId) {
this.userId = this.$route.query.userId; this.userId = this.$route.query.userId;
this.userName = this.$route.query.nickName; this.userName = this.$route.query.nickName;
this.projectId = this.$route.porjectId; this.projectId = this.$route.query.projectId;
} }
// //
}, },
@ -231,6 +328,9 @@ export default {
ele.showContent = false; ele.showContent = false;
return ele; return ele;
}); });
if (this.tableData.length == 0) {
this.handleAdd();
}
}); });
}, },
handleDelete(row, index) { handleDelete(row, index) {
@ -316,6 +416,50 @@ export default {
this.getVersionList(row.projectId, row, true); this.getVersionList(row.projectId, row, true);
} }
}, },
handleFile(row) {
this.dialogVisibleFile = true;
this.checkRow = row;
this.fileList = [...(row.fileList || []).map((ele) => ({ ...ele }))];
},
beforeUpload(file) {
this.fileLoading = true;
if (file.size > 1024 * 1024 * 100) {
this.fileLoading = false;
this.$message({
type: "warning",
message: "单个文件不能大于100M!",
});
return false;
}
},
successUpload(res, file, fileList) {
if (!fileList.filter((ele) => ele.percentage != 100).length) {
this.fileLoading = false;
}
if (res.code == 200) {
this.fileList.push({
fileName: res.originalFilename, //
filePath: res.filePath, //
fileNewName: res.newFileName, //
fileUrl: res.url,
});
} else {
this.$message({
type: "error",
message: res.msg,
});
}
},
cancalFile() {
this.dialogVisibleFile = false;
this.fileList = [];
},
saveFile() {
this.dialogVisibleFile = false;
this.checkRow.fileList = this.fileList;
},
async getAllProject() { async getAllProject() {
const response = await projectApi.listProject({ const response = await projectApi.listProject({
pageSize: 10000, pageSize: 10000,
@ -343,6 +487,7 @@ export default {
userId: this.userId, userId: this.userId,
demandId: "", demandId: "",
edit: true, edit: true,
fileList: [],
}; };
this.computedTime(0); this.computedTime(0);
if (this.workTimeList.length) this.tableData.push(row); if (this.workTimeList.length) this.tableData.push(row);
@ -408,6 +553,60 @@ export default {
row.showContent = false; row.showContent = false;
}); });
}, },
downFile(url) {
window.open(url);
},
delFile(row) {
if (row.id) {
this.$confirm("此操作将永久删除文件, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
systemApi.delFile(row.id).then((res) => {
this.fileList = this.fileList.filter(
(ele) => ele.fileNewName != row.fileNewName
);
this.$message({
type:'success',
message: "删除成功!"
})
});
});
} else {
this.fileList = this.fileList.filter(
(ele) => ele.fileNewName != row.fileNewName
);
this.$message({
type:'success',
message: "删除成功!"
})
}
},
getFileType(name) {
console.log(name);
var data = {
jpg: "image",
jpeg: "image",
png: "image",
gif: "image",
bmp: "image",
tiff: "image",
svg: "image",
pdf: "file",
doc: "file",
docx: "file",
xls: "file",
xlsx: "file",
txt: "file",
ppt: "file",
zip: "zip",
rar: "zip",
tar: "zip",
targz: "zip",
};
return data[name.split(".")[1]] || "file";
},
}, },
watch: { watch: {
$route(to, from) { $route(to, from) {
@ -443,6 +642,7 @@ export default {
}, 0) / 10 }, 0) / 10
).toFixed(1); ).toFixed(1);
}, },
}, },
mounted() { mounted() {
this.init(); this.init();
@ -487,4 +687,17 @@ export default {
.noneText { .noneText {
color: #999; color: #999;
} }
.downFileBox {
color: #1686d8;
cursor: pointer;
}
.fileBox{
img{
height: 18px;
}
}
.dialog-footer {
text-align: center;
margin-top: 20px;
}
</style> </style>