附件完成
parent
bc1c74ce55
commit
b1251e3bc5
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 |
|
@ -15,6 +15,22 @@
|
|||
/>
|
||||
</div>
|
||||
<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
|
||||
ref="customTableRef"
|
||||
:columns="columns"
|
||||
|
@ -101,6 +117,10 @@ export default {
|
|||
type: Function,
|
||||
default: () => true,
|
||||
},
|
||||
userIdList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -133,6 +153,9 @@ export default {
|
|||
userData: [],
|
||||
isInternalChange: false,
|
||||
selectAllData: [],
|
||||
searchForm: {
|
||||
nickName: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
emits: ["close", "confirm"],
|
||||
|
@ -196,10 +219,9 @@ export default {
|
|||
}
|
||||
},
|
||||
selectAll(arr) {
|
||||
let filterArr = this.selectAllData.filter((ele) =>
|
||||
!arr.some((item) => item.userId == ele.userId)
|
||||
let filterArr = this.selectAllData.filter(
|
||||
(ele) => !arr.some((item) => item.userId == ele.userId)
|
||||
);
|
||||
console.log(filterArr,11);
|
||||
|
||||
arr.forEach((ele) => {
|
||||
if (
|
||||
|
@ -208,20 +230,29 @@ export default {
|
|||
this.selectRow({ row: ele });
|
||||
});
|
||||
filterArr.forEach((ele) => {
|
||||
|
||||
this.selectRow({ row: ele});
|
||||
this.selectRow({ row: ele });
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
fetchUserList: async function () {
|
||||
const response = await systemApi.getUserList({
|
||||
pageNum: this.currentPage,
|
||||
pageSize: this.pageSize,
|
||||
deptId: this.currentDepartment,
|
||||
...this.searchForm,
|
||||
userIdList:this.userIdList,
|
||||
});
|
||||
this.userData = response.rows;
|
||||
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 () {
|
||||
const response = await systemApi.getDeptTree();
|
||||
|
@ -305,6 +336,13 @@ export default {
|
|||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
userIdList: {
|
||||
handler(newVal) {
|
||||
this.fetchUserList();
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetchTreeData();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 登录板块api
|
||||
// 公用板块
|
||||
|
||||
// 项目板块
|
||||
export const projectApi = {
|
||||
|
@ -92,6 +92,7 @@ export const workLogApi = {
|
|||
method: 'delete',
|
||||
}),
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 项目看板
|
||||
|
@ -133,6 +134,18 @@ export const systemApi = {
|
|||
url: '/system/user/deptTree',
|
||||
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}`,
|
||||
method: 'delete',
|
||||
}),
|
||||
getDemandDetail:(id) => request({
|
||||
url: `/demand/${id}`,
|
||||
method: 'get',
|
||||
}),
|
||||
delDemandBatch: (data) => request({
|
||||
url: `/demand/remove/batch/${data}`,
|
||||
method: 'delete',
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
style="width: 100%"
|
||||
@selection-change="handleSelectionChange"
|
||||
class="tableBox"
|
||||
:cell-class-name="setRowClass"
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="序号" width="70" type="index" />
|
||||
|
@ -223,11 +224,12 @@
|
|||
:currentSelectedUser="currentSelectedUser"
|
||||
@confirm="handleUserConfirm"
|
||||
@close="handleUserClose"
|
||||
:userIdList="projectUserList"
|
||||
/>
|
||||
<el-dialog
|
||||
:title="!editData.id ? '新建需求' : '修改需求'"
|
||||
:visible.sync="dialogVisibleAdd"
|
||||
width="780px"
|
||||
width="660px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form
|
||||
|
@ -237,6 +239,7 @@
|
|||
label-width="80px"
|
||||
class="addForm"
|
||||
ref="ruleForm"
|
||||
v-loading="fileLoading"
|
||||
>
|
||||
<el-form-item label="标题" class="longItem" prop="title">
|
||||
<el-input v-model="editData.title"></el-input>
|
||||
|
@ -321,7 +324,7 @@
|
|||
v-model="editData.createTime"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
style="width: 240px"
|
||||
style="width: 200px"
|
||||
value-format="yyyy-MM-dd 00:00:00"
|
||||
:picker-options="{
|
||||
disabledDate: setDateRange,
|
||||
|
@ -335,13 +338,53 @@
|
|||
type="date"
|
||||
placeholder="选择日期"
|
||||
value-format="yyyy-MM-dd 23:59:59"
|
||||
style="width: 240px"
|
||||
style="width: 200px"
|
||||
:picker-options="{
|
||||
disabledDate: setDateRange,
|
||||
}"
|
||||
>
|
||||
</el-date-picker>
|
||||
</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>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisibleAdd = false">取消</el-button>
|
||||
|
@ -352,8 +395,12 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { demandApi, systemApi } from "@/utils/api";
|
||||
import { demandApi, systemApi, projectApi } from "@/utils/api";
|
||||
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 {
|
||||
name: "MainContentTable",
|
||||
|
@ -414,7 +461,10 @@ export default {
|
|||
endTime: "",
|
||||
priority: "",
|
||||
projectId: "",
|
||||
fileList: [],
|
||||
},
|
||||
token: getToken(),
|
||||
fileUpload: systemApi.fileUpload,
|
||||
rules: {
|
||||
title: [
|
||||
{ required: true, message: "请输入标题", trigger: "change" },
|
||||
|
@ -463,6 +513,11 @@ export default {
|
|||
value: index + 1,
|
||||
label: index + 1 + "天",
|
||||
})),
|
||||
projectUserList: [],
|
||||
fileLoading: false,
|
||||
filePng,
|
||||
zipPng,
|
||||
imagePng,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
|
@ -484,6 +539,7 @@ export default {
|
|||
},
|
||||
projectId(newVal) {
|
||||
this.editData.projectId = newVal;
|
||||
this.getProjectUser();
|
||||
},
|
||||
projectName(newVal) {
|
||||
this.editData.projectName = newVal;
|
||||
|
@ -521,6 +577,7 @@ export default {
|
|||
endTime: "",
|
||||
priority: "",
|
||||
projectId: "",
|
||||
fileList: [],
|
||||
};
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.ruleForm) {
|
||||
|
@ -534,19 +591,20 @@ export default {
|
|||
this.editData.projectName = this.projectName;
|
||||
},
|
||||
handleEdit(row) {
|
||||
// if (row.demandStatus == 4) {
|
||||
// this.$message({
|
||||
// type: "warning",
|
||||
// message: "需求已关闭,无法编辑!",
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
this.editData = row;
|
||||
this.editData.projectId = this.projectId;
|
||||
this.editData.projectName = this.projectName;
|
||||
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) {
|
||||
// 实现删除逻辑
|
||||
this.$confirm("此操作将永久删除该需求, 是否继续?", "提示", {
|
||||
|
@ -733,31 +791,6 @@ export default {
|
|||
});
|
||||
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) {
|
||||
demandApi.eidtDemand(this.editData).then((res) => {
|
||||
this.$message({
|
||||
|
@ -853,6 +886,100 @@ export default {
|
|||
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() {
|
||||
this.getDictData();
|
||||
|
@ -926,11 +1053,16 @@ export default {
|
|||
background-color: #50b6aa !important;
|
||||
}
|
||||
}
|
||||
::v-deep .status-tag.closed .el-radio__inner,
|
||||
::v-deep .status-tag.wait .el-radio__inner {
|
||||
border-color: #999999 !important;
|
||||
::v-deep .status-tag.closed .el-radio__inner {
|
||||
border-color: #ccc !important;
|
||||
&::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 {
|
||||
|
@ -948,12 +1080,13 @@ export default {
|
|||
// background-color: #e6f7f5;
|
||||
}
|
||||
|
||||
::v-deep .status-tag.closed .el-radio__label,
|
||||
::v-deep .status-tag.wait .el-radio__label {
|
||||
color: #999999 !important;
|
||||
color: #999 !important;
|
||||
// background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
::v-deep .status-tag.closed .el-radio__label {
|
||||
color: #ccc !important;
|
||||
}
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
|
@ -966,6 +1099,12 @@ export default {
|
|||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
::v-deep .disabled.el-table__cell {
|
||||
color: #ccc;
|
||||
.el-dropdown-link {
|
||||
color: #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-button {
|
||||
border-radius: 4px;
|
||||
|
@ -1009,7 +1148,7 @@ export default {
|
|||
::v-deep .addForm {
|
||||
.el-input__inner {
|
||||
// width: 100%;
|
||||
width: 240px;
|
||||
width: 200px;
|
||||
}
|
||||
.el-form-item {
|
||||
width: 48%;
|
||||
|
@ -1068,4 +1207,28 @@ export default {
|
|||
font-weight: 600;
|
||||
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>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<template>
|
||||
<div class="project-management">
|
||||
<div class="project-management"
|
||||
v-loading="fileLoading"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
|
@ -115,6 +117,50 @@
|
|||
</el-form-item>
|
||||
</el-col>
|
||||
</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>
|
||||
<div class="form-actions jcc" v-show="!isEditing">
|
||||
<el-button
|
||||
|
@ -263,6 +309,10 @@
|
|||
import CustomTable from "@/components/CustomTable.vue";
|
||||
import SelectUser from "@/components/SelectUser.vue";
|
||||
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 {
|
||||
components: {
|
||||
|
@ -288,9 +338,12 @@ export default {
|
|||
budgetDate: 0,
|
||||
state: 0,
|
||||
dataState: 0,
|
||||
fileList:[]
|
||||
},
|
||||
postOptions: [],
|
||||
statusList: [],
|
||||
fileUpload: systemApi.fileUpload,
|
||||
|
||||
columns: [
|
||||
{ prop: "userName", label: "姓名" },
|
||||
{ prop: "post", label: "项目职位" },
|
||||
|
@ -298,6 +351,8 @@ export default {
|
|||
{ prop: "operation", label: "操作", width: "250px" },
|
||||
],
|
||||
tableData: [],
|
||||
fileLoading: false,
|
||||
|
||||
currentEditingRow: {},
|
||||
currentSelectedUser: [],
|
||||
projectManagerSelectedUser: [],
|
||||
|
@ -322,7 +377,15 @@ export default {
|
|||
budgetDate: [
|
||||
{ required: true, message: "预算天数为必填", trigger: "blur" },
|
||||
],
|
||||
fileList: [
|
||||
{ required: true, message: "预算天数为必填", trigger: "blur" },
|
||||
],
|
||||
},
|
||||
filePng,
|
||||
zipPng,
|
||||
imagePng,
|
||||
token: getToken(),
|
||||
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
|
@ -571,6 +634,7 @@ export default {
|
|||
projectState,
|
||||
budgetDate,
|
||||
state,
|
||||
fileList
|
||||
} = response.data;
|
||||
let startDate = projectData.startDate.split(" ")[0];
|
||||
let endDate = projectData.endDate.split(" ")[0];
|
||||
|
@ -585,6 +649,7 @@ export default {
|
|||
endDate,
|
||||
budgetDate,
|
||||
state,
|
||||
fileList
|
||||
};
|
||||
this.updateProjectState(); // 更新项目状态
|
||||
} catch (error) {
|
||||
|
@ -627,6 +692,89 @@ export default {
|
|||
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() {
|
||||
const projectId = this.$route.params.id || this.$route.query.id;
|
||||
|
@ -779,4 +927,30 @@ export default {
|
|||
height: 64px;
|
||||
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>
|
||||
|
|
|
@ -37,6 +37,12 @@
|
|||
hasLog: calendarList.filter(
|
||||
(ele) => ele.date == data.day + ' 00:00:00' && ele.state != -1
|
||||
).length,
|
||||
timeout: isTimeOut(
|
||||
data.day,
|
||||
calendarList.find(
|
||||
(ele) => ele.date == data.day + ' 00:00:00' && ele.state == -1
|
||||
)
|
||||
),
|
||||
}"
|
||||
>
|
||||
{{ data.day.split("-")[2] }}
|
||||
|
@ -104,6 +110,15 @@ export default {
|
|||
isOverDay(data) {
|
||||
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() {
|
||||
if (this.$route.query.userId) {
|
||||
this.userId = this.$route.query.userId;
|
||||
|
@ -181,6 +196,11 @@ export default {
|
|||
border-radius: 50%;
|
||||
color: #fff;
|
||||
}
|
||||
.timeout {
|
||||
background: #f7c940;
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
}
|
||||
td {
|
||||
border: none;
|
||||
padding: 10px 0;
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
</el-input>
|
||||
<div
|
||||
style="margin-top: 10px; text-align: right"
|
||||
v-show="!disableTable&&scope.row.edit"
|
||||
v-show="!disableTable && scope.row.edit"
|
||||
>
|
||||
<el-button type="primary" @click="saveContent(scope.row, 1)"
|
||||
>确认</el-button
|
||||
|
@ -160,12 +160,16 @@
|
|||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120">
|
||||
<el-table-column label="操作" width="200">
|
||||
<template #default="scope">
|
||||
<div v-show="!disableTable">
|
||||
<el-button type="text" @click="handleFile(scope.row)">
|
||||
附件详情
|
||||
</el-button>
|
||||
<el-button type="text" @click="handleEdit(scope.row)">
|
||||
{{ scope.row.loggerId && !scope.row.edit ? "编辑" : "确认" }}
|
||||
</el-button>
|
||||
|
||||
<el-button
|
||||
type="text"
|
||||
@click="handleDelete(scope.row, scope.$index)"
|
||||
|
@ -177,12 +181,96 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
<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 {
|
||||
name: "RightTable",
|
||||
props: {
|
||||
|
@ -207,6 +295,15 @@ export default {
|
|||
hasTimeLong: 0,
|
||||
workTimeList: [],
|
||||
oldContent: "",
|
||||
dialogVisibleFile: false,
|
||||
fileList: [],
|
||||
checkRow: {},
|
||||
fileUpload: systemApi.fileUpload,
|
||||
token: getToken(),
|
||||
fileLoading: false,
|
||||
filePng,
|
||||
zipPng,
|
||||
imagePng,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -214,7 +311,7 @@ export default {
|
|||
if (this.$route.query.userId) {
|
||||
this.userId = this.$route.query.userId;
|
||||
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;
|
||||
return ele;
|
||||
});
|
||||
if (this.tableData.length == 0) {
|
||||
this.handleAdd();
|
||||
}
|
||||
});
|
||||
},
|
||||
handleDelete(row, index) {
|
||||
|
@ -316,6 +416,50 @@ export default {
|
|||
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() {
|
||||
const response = await projectApi.listProject({
|
||||
pageSize: 10000,
|
||||
|
@ -343,6 +487,7 @@ export default {
|
|||
userId: this.userId,
|
||||
demandId: "",
|
||||
edit: true,
|
||||
fileList: [],
|
||||
};
|
||||
this.computedTime(0);
|
||||
if (this.workTimeList.length) this.tableData.push(row);
|
||||
|
@ -408,6 +553,60 @@ export default {
|
|||
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: {
|
||||
$route(to, from) {
|
||||
|
@ -443,6 +642,7 @@ export default {
|
|||
}, 0) / 10
|
||||
).toFixed(1);
|
||||
},
|
||||
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
|
@ -487,4 +687,17 @@ export default {
|
|||
.noneText {
|
||||
color: #999;
|
||||
}
|
||||
.downFileBox {
|
||||
color: #1686d8;
|
||||
cursor: pointer;
|
||||
}
|
||||
.fileBox{
|
||||
img{
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
.dialog-footer {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue