parent
b1251e3bc5
commit
b3bd2eff61
|
@ -121,6 +121,11 @@ export default {
|
|||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
isFilter: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -346,7 +351,9 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
this.fetchTreeData();
|
||||
this.fetchUserList();
|
||||
if(!this.isFilter){
|
||||
this.fetchUserList();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -134,7 +134,7 @@ export const systemApi = {
|
|||
url: '/system/user/deptTree',
|
||||
method: 'get',
|
||||
}),
|
||||
fileUpload: '/common/upload',
|
||||
fileUpload: process.env.NODE_ENV == 'development' ? '/common/upload' : '/prod-api/common/upload',
|
||||
downFile: (data) => request({
|
||||
url: '/common/download',
|
||||
method: 'get',
|
||||
|
@ -145,6 +145,11 @@ export const systemApi = {
|
|||
method: 'delete',
|
||||
|
||||
}),
|
||||
delFileBatch: (id) => request({
|
||||
url: `/business/project/file/batch/${id}`,
|
||||
method: 'delete',
|
||||
|
||||
}),
|
||||
|
||||
}
|
||||
|
||||
|
@ -195,16 +200,26 @@ export const taskApi = {
|
|||
url: `/task/${id}`,
|
||||
method: 'delete',
|
||||
}),
|
||||
delTaskModule: (id) => request({
|
||||
url: `/examine/template/${id}`,
|
||||
method: 'delete',
|
||||
}),
|
||||
getTaskSet: (id) => request({
|
||||
url: `/task/target/${id}`,
|
||||
method: 'get',
|
||||
}),
|
||||
setTaskSet: (data) => request({
|
||||
url: `/task/config/update`,
|
||||
method: 'put',
|
||||
data: data,
|
||||
|
||||
getTaskModel: (data) => request({
|
||||
url: `/examine/template/list`,
|
||||
method: 'get',
|
||||
params: data,
|
||||
}),
|
||||
// 获取模板配置
|
||||
getTaskModelSet: (id) => request({
|
||||
url: `/examine/template/list/${id}`,
|
||||
method: 'get',
|
||||
}),
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -250,7 +265,7 @@ export const demandApi = {
|
|||
url: `/demand/${data}`,
|
||||
method: 'delete',
|
||||
}),
|
||||
getDemandDetail:(id) => request({
|
||||
getDemandDetail: (id) => request({
|
||||
url: `/demand/${id}`,
|
||||
method: 'get',
|
||||
}),
|
||||
|
|
|
@ -3,54 +3,25 @@
|
|||
<div class="topTitle">需求列表</div>
|
||||
<!-- 搜索筛选区域 -->
|
||||
<div class="search-filters">
|
||||
<el-input
|
||||
v-model="filters.title"
|
||||
placeholder="请输入"
|
||||
class="filter-input"
|
||||
>
|
||||
<el-input v-model="filters.title" placeholder="请输入" class="filter-input">
|
||||
<template #prefix>
|
||||
<div>标题名称</div>
|
||||
</template>
|
||||
</el-input>
|
||||
|
||||
<el-input
|
||||
v-model="filters.responsiblePersonName"
|
||||
placeholder="请选择负责人"
|
||||
class="filter-input"
|
||||
readonly
|
||||
@focus="openUser('search')"
|
||||
>
|
||||
<el-input v-model="filters.responsiblePersonName" placeholder="请选择负责人" class="filter-input" readonly
|
||||
@focus="openUser('search')">
|
||||
<template #prefix>负责人</template>
|
||||
</el-input>
|
||||
|
||||
<el-select
|
||||
v-model="filters.demandStatus"
|
||||
placeholder="不限"
|
||||
class="filter-select"
|
||||
clearable
|
||||
>
|
||||
<el-select v-model="filters.demandStatus" placeholder="不限" class="filter-select" clearable>
|
||||
<template #prefix>需求状态</template>
|
||||
<el-option
|
||||
v-for="item in statusList"
|
||||
:key="item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictValue"
|
||||
/>
|
||||
<el-option v-for="item in statusList" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
|
||||
</el-select>
|
||||
|
||||
<el-select
|
||||
v-model="filters.priority"
|
||||
placeholder="不限"
|
||||
class="filter-select"
|
||||
clearable
|
||||
>
|
||||
<el-select v-model="filters.priority" placeholder="不限" class="filter-select" clearable>
|
||||
<template #prefix>优先级</template>
|
||||
<el-option
|
||||
v-for="item in priorityList"
|
||||
:key="item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictValue"
|
||||
/>
|
||||
<el-option v-for="item in priorityList" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
|
||||
</el-select>
|
||||
|
||||
<div class="filter-buttons">
|
||||
|
@ -69,13 +40,8 @@
|
|||
</div>
|
||||
|
||||
<!-- 表格区域 -->
|
||||
<el-table
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
@selection-change="handleSelectionChange"
|
||||
class="tableBox"
|
||||
:cell-class-name="setRowClass"
|
||||
>
|
||||
<el-table :data="tableData" 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" />
|
||||
<el-table-column label="版本号" prop="versionNumber" />
|
||||
|
@ -83,48 +49,29 @@
|
|||
<el-table-column label="需求状态">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<el-dropdown
|
||||
trigger="click"
|
||||
placement="bottom"
|
||||
:key="scope.row.id"
|
||||
@command="
|
||||
(data) => {
|
||||
changeRow(data, 'demandStatus', scope.row);
|
||||
}
|
||||
"
|
||||
>
|
||||
<el-radio
|
||||
v-model="scope.row.demandStatus"
|
||||
:label="scope.row.demandStatus"
|
||||
:class="['status-tag', getStatusClass(scope.row.demandStatus)]"
|
||||
>
|
||||
<el-dropdown trigger="click" placement="bottom" :key="scope.row.id" @command="
|
||||
(data) => {
|
||||
changeRow(data, 'demandStatus', scope.row);
|
||||
}
|
||||
">
|
||||
<el-radio v-model="scope.row.demandStatus" :label="scope.row.demandStatus"
|
||||
:class="['status-tag', getStatusClass(scope.row.demandStatus)]">
|
||||
{{
|
||||
statusList[scope.row.demandStatus]
|
||||
? statusList[scope.row.demandStatus].dictLabel
|
||||
: ""
|
||||
}}</el-radio
|
||||
>
|
||||
}}</el-radio>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item
|
||||
v-for="item in statusList"
|
||||
:key="item.dictValue"
|
||||
:command="item.dictValue"
|
||||
:class="{
|
||||
tableSelect1: true,
|
||||
selectedItem1: item.dictValue == scope.row.demandStatus,
|
||||
}"
|
||||
><el-radio
|
||||
v-model="scope.row.demandStatus"
|
||||
:label="scope.row.demandStatus"
|
||||
:class="['status-tag', getStatusClass(item.dictValue)]"
|
||||
>
|
||||
<el-dropdown-item v-for="item in statusList" :key="item.dictValue" :command="item.dictValue" :class="{
|
||||
tableSelect1: true,
|
||||
selectedItem1: item.dictValue == scope.row.demandStatus,
|
||||
}"><el-radio v-model="scope.row.demandStatus" :label="scope.row.demandStatus"
|
||||
:class="['status-tag', getStatusClass(item.dictValue)]">
|
||||
{{
|
||||
statusList[item.dictValue]
|
||||
? statusList[item.dictValue].dictLabel
|
||||
: ""
|
||||
}}</el-radio
|
||||
></el-dropdown-item
|
||||
>
|
||||
}}</el-radio></el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
@ -152,39 +99,28 @@
|
|||
<el-table-column label="优先级" prop="priority">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<el-dropdown
|
||||
trigger="click"
|
||||
placement="bottom"
|
||||
:key="scope.row.id"
|
||||
@command="
|
||||
(data) => {
|
||||
changeRow(data, 'priority', scope.row);
|
||||
}
|
||||
"
|
||||
>
|
||||
<el-dropdown trigger="click" placement="bottom" :key="scope.row.id" @command="
|
||||
(data) => {
|
||||
changeRow(data, 'priority', scope.row);
|
||||
}
|
||||
">
|
||||
<span class="el-dropdown-link">
|
||||
{{
|
||||
priorityList.find(
|
||||
(ele) => ele.dictValue == scope.row.priority
|
||||
)
|
||||
? priorityList.find(
|
||||
(ele) => ele.dictValue == scope.row.priority
|
||||
).dictLabel
|
||||
(ele) => ele.dictValue == scope.row.priority
|
||||
).dictLabel
|
||||
: ""
|
||||
}}
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item
|
||||
v-for="item in priorityList"
|
||||
:key="item.dictValue"
|
||||
:command="item.dictValue"
|
||||
:class="{
|
||||
tableSelect2: true,
|
||||
selectedItem2: item.dictValue == scope.row.priority,
|
||||
}"
|
||||
>{{ item.dictLabel }}</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item v-for="item in priorityList" :key="item.dictValue" :command="item.dictValue" :class="{
|
||||
tableSelect2: true,
|
||||
selectedItem2: item.dictValue == scope.row.priority,
|
||||
}">{{ item.dictLabel }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
@ -196,11 +132,7 @@
|
|||
<el-button type="text" @click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
type="text"
|
||||
@click="handleDelete(scope.row)"
|
||||
style="color: #666"
|
||||
>
|
||||
<el-button type="text" @click="handleDelete(scope.row)" style="color: #666">
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
|
@ -211,36 +143,16 @@
|
|||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<span class="total">共 {{ total }} 条</span>
|
||||
<el-pagination
|
||||
v-model:current-page="currentPage"
|
||||
v-model:page-size="pageSize"
|
||||
:total="total"
|
||||
@current-change="handlePageChange"
|
||||
/>
|
||||
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :total="total"
|
||||
@current-change="handlePageChange" />
|
||||
</div>
|
||||
<SelectUser
|
||||
:dialogVisible="userSelectDialogVisible"
|
||||
:multiSelect="false"
|
||||
:currentSelectedUser="currentSelectedUser"
|
||||
@confirm="handleUserConfirm"
|
||||
@close="handleUserClose"
|
||||
:userIdList="projectUserList"
|
||||
/>
|
||||
<el-dialog
|
||||
:title="!editData.id ? '新建需求' : '修改需求'"
|
||||
:visible.sync="dialogVisibleAdd"
|
||||
width="660px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form
|
||||
:inline="true"
|
||||
:rules="rules"
|
||||
:model="editData"
|
||||
label-width="80px"
|
||||
class="addForm"
|
||||
ref="ruleForm"
|
||||
v-loading="fileLoading"
|
||||
>
|
||||
<SelectUser :dialogVisible="userSelectDialogVisible" :multiSelect="false" :currentSelectedUser="currentSelectedUser"
|
||||
@confirm="handleUserConfirm" @close="handleUserClose" :userIdList="projectUserList" :isFilter="true"
|
||||
ref="selectUserRef" />
|
||||
<el-dialog :title="!editData.id ? '新建需求' : '修改需求'" :visible.sync="dialogVisibleAdd" width="660px"
|
||||
:close-on-click-modal="false">
|
||||
<el-form :inline="true" :rules="rules" :model="editData" 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>
|
||||
</el-form-item>
|
||||
|
@ -248,136 +160,66 @@
|
|||
<el-input v-model="editData.projectName" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="所属版本" prop="versionId">
|
||||
<el-select
|
||||
v-model="editData.versionId"
|
||||
placeholder="请选择所属版本"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in versionList"
|
||||
:key="item.nodeId"
|
||||
:label="item.title"
|
||||
:value="item.id"
|
||||
/>
|
||||
<el-select v-model="editData.versionId" placeholder="请选择所属版本" clearable>
|
||||
<el-option v-for="item in versionList" :key="item.nodeId" :label="item.title" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="负责人" prop="responsiblePerson">
|
||||
<el-input
|
||||
v-model="editData.responsiblePersonName"
|
||||
placeholder="请选择负责人"
|
||||
class="filter-input"
|
||||
readonly
|
||||
@focus="openUser('add')"
|
||||
>
|
||||
<el-input v-model="editData.responsiblePersonName" placeholder="请选择负责人" class="filter-input" readonly
|
||||
@focus="openUser('add')">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="需求状态" prop="demandStatus">
|
||||
<el-select
|
||||
v-model="editData.demandStatus"
|
||||
placeholder="请选择需求状态"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in statusList"
|
||||
:key="item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictValue"
|
||||
/>
|
||||
<el-select v-model="editData.demandStatus" placeholder="请选择需求状态" clearable>
|
||||
<el-option v-for="item in statusList" :key="item.dictValue" :label="item.dictLabel"
|
||||
:value="item.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="优先级" prop="priority">
|
||||
<el-select
|
||||
v-model="editData.priority"
|
||||
placeholder="请选择优先级"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in priorityList"
|
||||
:key="item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictValue"
|
||||
/>
|
||||
<el-select v-model="editData.priority" placeholder="请选择优先级" clearable>
|
||||
<el-option v-for="item in priorityList" :key="item.dictValue" :label="item.dictLabel"
|
||||
:value="item.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计工时" prop="estimatedWorkHours">
|
||||
<el-select
|
||||
v-model="editData.estimatedWorkHours"
|
||||
filterable
|
||||
allow-create
|
||||
default-first-option
|
||||
placeholder="请输入预计工时"
|
||||
@change="changeTime"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
>
|
||||
<el-select v-model="editData.estimatedWorkHours" filterable allow-create default-first-option
|
||||
placeholder="请输入预计工时" @change="changeTime" clearable>
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" prop="createTime">
|
||||
<el-date-picker
|
||||
@change="changeTime"
|
||||
v-model="editData.createTime"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
style="width: 200px"
|
||||
value-format="yyyy-MM-dd 00:00:00"
|
||||
:picker-options="{
|
||||
<el-date-picker @change="changeTime" v-model="editData.createTime" type="date" placeholder="选择日期"
|
||||
style="width: 200px" value-format="yyyy-MM-dd 00:00:00" :picker-options="{
|
||||
disabledDate: setDateRange,
|
||||
}"
|
||||
>
|
||||
}">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间" prop="endTime">
|
||||
<el-date-picker
|
||||
v-model="editData.endTime"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
value-format="yyyy-MM-dd 23:59:59"
|
||||
style="width: 200px"
|
||||
:picker-options="{
|
||||
<el-date-picker v-model="editData.endTime" type="date" placeholder="选择日期" value-format="yyyy-MM-dd 23:59:59"
|
||||
style="width: 200px" :picker-options="{
|
||||
disabledDate: setDateRange,
|
||||
}"
|
||||
>
|
||||
}">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="附件" class="longItem" prop="endTime">
|
||||
<el-form-item label="附件" class="longItem" 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="{
|
||||
<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>
|
||||
}" :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 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>
|
||||
<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>
|
||||
|
@ -518,6 +360,7 @@ export default {
|
|||
filePng,
|
||||
zipPng,
|
||||
imagePng,
|
||||
delFileArr: []
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
|
@ -591,7 +434,7 @@ export default {
|
|||
this.editData.projectName = this.projectName;
|
||||
},
|
||||
handleEdit(row) {
|
||||
this.editData = row;
|
||||
this.editData = Object.assign({}, row);
|
||||
this.editData.projectId = this.projectId;
|
||||
this.editData.projectName = this.projectName;
|
||||
this.dialogVisibleAdd = true;
|
||||
|
@ -621,7 +464,7 @@ export default {
|
|||
this.resetList("del");
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
.catch(() => { });
|
||||
},
|
||||
handleBatchDelete() {
|
||||
if (!this.selectedRows.length) {
|
||||
|
@ -724,30 +567,6 @@ export default {
|
|||
this.userSelectDialogVisible = false;
|
||||
},
|
||||
eidtDemandRow(row, label, old) {
|
||||
// if (this.checkedRow.demandStatus == 4) {
|
||||
// this.$confirm("需求关闭后将无法操作和使用, 是否继续?", "提示", {
|
||||
// confirmButtonText: "确定",
|
||||
// cancelButtonText: "取消",
|
||||
// type: "warning",
|
||||
// })
|
||||
// .then(() => {
|
||||
// demandApi
|
||||
// .eidtDemand(this.checkedRow)
|
||||
// .then((res) => {
|
||||
// this.$message({
|
||||
// message: "修改成功",
|
||||
// type: "success",
|
||||
// });
|
||||
// this.getDemandList();
|
||||
// })
|
||||
// .catch((res) => {
|
||||
// row[label] = old;
|
||||
// });
|
||||
// })
|
||||
// .catch(() => {
|
||||
// row[label] = old;
|
||||
// });
|
||||
// } else {
|
||||
demandApi
|
||||
.eidtDemand(this.checkedRow)
|
||||
.then((res) => {
|
||||
|
@ -808,11 +627,17 @@ export default {
|
|||
this.resetList("add", res.data);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// }
|
||||
});
|
||||
},
|
||||
resetList(type, data) {
|
||||
async resetList(type, data) {
|
||||
if (this.delFileArr.length) {
|
||||
await systemApi.delFileBatch(this.delFileArr.join(','))
|
||||
this.delFileArr = []
|
||||
}
|
||||
let refreshId = "";
|
||||
if (type == "edit") {
|
||||
if (this.editData.versionId) {
|
||||
|
@ -894,6 +719,7 @@ export default {
|
|||
res1.data.projectLeader,
|
||||
...res2.data?.map((ele) => ele.userId),
|
||||
];
|
||||
|
||||
},
|
||||
setRowClass({ row }) {
|
||||
if (row.demandStatus == 4) {
|
||||
|
@ -903,7 +729,7 @@ export default {
|
|||
beforeUpload(file) {
|
||||
this.fileLoading = true;
|
||||
if (file.size > 1024 * 1024 * 100) {
|
||||
this.fileLoading = false;
|
||||
this.fileLoading = false;
|
||||
|
||||
this.$message({
|
||||
type: "warning",
|
||||
|
@ -912,8 +738,8 @@ export default {
|
|||
return false;
|
||||
}
|
||||
},
|
||||
successUpload(res,file,fileList) {
|
||||
if(!fileList.filter((ele)=>ele.percentage!=100).length){
|
||||
successUpload(res, file, fileList) {
|
||||
if (!fileList.filter((ele) => ele.percentage != 100).length) {
|
||||
this.fileLoading = false;
|
||||
}
|
||||
if (res.code == 200) {
|
||||
|
@ -924,6 +750,8 @@ export default {
|
|||
fileUrl: res.url,
|
||||
});
|
||||
} else {
|
||||
this.fileLoading = false;
|
||||
|
||||
this.$message({
|
||||
type: "error",
|
||||
message: res.msg,
|
||||
|
@ -937,48 +765,48 @@ export default {
|
|||
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: "删除成功!"
|
||||
})
|
||||
});
|
||||
this.editData.fileList = this.editData.fileList.filter(
|
||||
(ele) => ele.fileNewName != row.fileNewName
|
||||
);
|
||||
this.delFileArr.push(row.id)
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: "删除成功!"
|
||||
})
|
||||
|
||||
});
|
||||
} else {
|
||||
this.editData.fileList = this.editData.fileList.filter(
|
||||
(ele) => ele.fileNewName != row.fileNewName
|
||||
);
|
||||
this.$message({
|
||||
type:'success',
|
||||
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'
|
||||
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() {
|
||||
|
@ -1023,6 +851,7 @@ export default {
|
|||
padding-left: 5px !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .status-tag .el-radio__inner {
|
||||
height: 18px !important;
|
||||
width: 18px !important;
|
||||
|
@ -1030,41 +859,53 @@ export default {
|
|||
text-align: center;
|
||||
margin-bottom: 1px;
|
||||
background: #fff !important;
|
||||
|
||||
&::after {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .status-tag.pending .el-radio__inner {
|
||||
border-color: #ff7d00;
|
||||
|
||||
&::after {
|
||||
background-color: #ff7d00 !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .status-tag.in-progress .el-radio__inner {
|
||||
border-color: #4096ff !important;
|
||||
|
||||
&::after {
|
||||
background-color: #4096ff !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .status-tag.completed .el-radio__inner {
|
||||
border-color: #50b6aa !important;
|
||||
|
||||
&::after {
|
||||
background-color: #50b6aa !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .status-tag.closed .el-radio__inner {
|
||||
border-color: #ccc !important;
|
||||
|
||||
&::after {
|
||||
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 {
|
||||
color: #ff7d00 !important;
|
||||
// background-color: #fff7e6;
|
||||
|
@ -1084,9 +925,11 @@ export default {
|
|||
color: #999 !important;
|
||||
// background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
::v-deep .status-tag.closed .el-radio__label {
|
||||
color: #ccc !important;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
|
@ -1099,8 +942,10 @@ export default {
|
|||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
::v-deep .disabled.el-table__cell {
|
||||
color: #ccc;
|
||||
|
||||
.el-dropdown-link {
|
||||
color: #ccc;
|
||||
}
|
||||
|
@ -1131,12 +976,15 @@ export default {
|
|||
padding-left: 10px !important;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.search-filters ::v-deep .el-input__inner {
|
||||
padding-left: 80px !important;
|
||||
|
||||
::placeholder {
|
||||
color: #bbb;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-button--primary {
|
||||
background-color: #4096ff;
|
||||
}
|
||||
|
@ -1145,35 +993,44 @@ export default {
|
|||
border-color: #4096ff;
|
||||
background-color: #4096ff;
|
||||
}
|
||||
|
||||
::v-deep .addForm {
|
||||
.el-input__inner {
|
||||
// width: 100%;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
width: 48%;
|
||||
}
|
||||
|
||||
.el-input--prefix .el-input__inner {
|
||||
padding-left: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .longItem {
|
||||
width: 100% !important;
|
||||
|
||||
.el-form-item__content {
|
||||
width: 82.2%;
|
||||
|
||||
.el-input__inner {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tableSelect1 {
|
||||
width: 150px;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.tableSelect2 {
|
||||
width: 100px;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.selectedItem1 {
|
||||
&::after {
|
||||
content: "✔";
|
||||
|
@ -1184,9 +1041,11 @@ export default {
|
|||
color: #4096ff;
|
||||
}
|
||||
}
|
||||
|
||||
.selectedItem2 {
|
||||
color: #4096ff;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "✔";
|
||||
width: 10px;
|
||||
|
@ -1196,17 +1055,20 @@ export default {
|
|||
color: #4096ff;
|
||||
}
|
||||
}
|
||||
|
||||
.tableBox {
|
||||
.el-radio {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.topTitle {
|
||||
padding: 0 20px 20px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.fileRow {
|
||||
height: 38px;
|
||||
padding: 0 10px;
|
||||
|
@ -1218,15 +1080,18 @@ export default {
|
|||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
img{
|
||||
|
||||
img {
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
.fileItem{
|
||||
|
||||
.fileItem {
|
||||
gap: 10px;
|
||||
cursor: pointer;
|
||||
cursor: pointer;
|
||||
}
|
||||
.fileBox{
|
||||
|
||||
.fileBox {
|
||||
max-height: 200px;
|
||||
overflow: auto;
|
||||
padding-right: 10px;
|
||||
|
|
|
@ -65,11 +65,22 @@
|
|||
class="nodeIcon"
|
||||
/>
|
||||
<!-- 节点文本 -->
|
||||
<span
|
||||
:class="['nodeLabel', data.nodeId === selectedId ? 'selected' : '']"
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="light"
|
||||
:content="data.title"
|
||||
placement="top"
|
||||
:disabled="data.title.length > 8 ? false : true"
|
||||
>
|
||||
{{ data.title }}
|
||||
</span>
|
||||
<div
|
||||
:class="[
|
||||
'nodeLabel',
|
||||
data.nodeId === selectedId ? 'selected' : '',
|
||||
]"
|
||||
>
|
||||
{{ data.title }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
|
||||
<!-- 右侧数字标记 -->
|
||||
<span
|
||||
|
@ -164,7 +175,7 @@ export default {
|
|||
})
|
||||
.then((res) => {
|
||||
if (!res.data.length) {
|
||||
this.treeData=[]
|
||||
this.treeData = [];
|
||||
return;
|
||||
}
|
||||
res.data = res.data.map((ele) => {
|
||||
|
@ -221,6 +232,13 @@ export default {
|
|||
});
|
||||
return;
|
||||
}
|
||||
if (this.demandData.name.length > 10) {
|
||||
this.$message({
|
||||
message: "版本号限制10个字符",
|
||||
type: "warning",
|
||||
});
|
||||
return;
|
||||
}
|
||||
let param = {
|
||||
projectId: this.projectId,
|
||||
versionNumber: this.demandData.name,
|
||||
|
@ -348,6 +366,11 @@ export default {
|
|||
font-weight: 600;
|
||||
line-height: 36px;
|
||||
color: #333;
|
||||
max-width: 160px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.nodeLabel.selected {
|
||||
|
|
|
@ -1,119 +1,61 @@
|
|||
<template>
|
||||
<div class="project-management"
|
||||
v-loading="fileLoading"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="rules"
|
||||
label-width="120px"
|
||||
class="custom-form"
|
||||
>
|
||||
<div class="project-management" v-loading="fileLoading">
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px" class="custom-form">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="项目名称" prop="projectName">
|
||||
<div>
|
||||
<el-input
|
||||
v-model="formData.projectName"
|
||||
placeholder="请输入项目名称"
|
||||
:disabled="isEditing"
|
||||
class="full-width longInput"
|
||||
/>
|
||||
<el-input v-model="formData.projectName" placeholder="请输入项目名称" :disabled="isEditing"
|
||||
class="full-width longInput" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="项目编码" prop="projectCode">
|
||||
<el-input
|
||||
v-model="formData.projectCode"
|
||||
class="full-width"
|
||||
:disabled="isEditing"
|
||||
/>
|
||||
<el-input v-model="formData.projectCode" class="full-width" :disabled="isEditing" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="项目负责人" prop="projectLeader">
|
||||
<el-input
|
||||
v-model="formData.projectLeaderName"
|
||||
placeholder="选择项目负责人"
|
||||
readonly
|
||||
:disabled="isEditing"
|
||||
@click.native="openProjectManagerSelect"
|
||||
>
|
||||
<el-button
|
||||
size="mini"
|
||||
slot="append"
|
||||
icon="el-icon-s-custom"
|
||||
></el-button
|
||||
></el-input>
|
||||
<el-input v-model="formData.projectLeaderName" placeholder="选择项目负责人" readonly :disabled="isEditing"
|
||||
@click.native="openProjectManagerSelect">
|
||||
<el-button size="mini" slot="append" icon="el-icon-s-custom"></el-button></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="数据状态" prop="dataState" style="display: none">
|
||||
<el-select
|
||||
v-model="formData.dataState"
|
||||
placeholder="根据时间自动生成"
|
||||
disabled
|
||||
class="full-width"
|
||||
>
|
||||
<el-select v-model="formData.dataState" placeholder="根据时间自动生成" disabled class="full-width">
|
||||
<el-option label="未启动" value="0" />
|
||||
<el-option label="进行中" value="1" />
|
||||
<el-option label="已完成" value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="项目状态" prop="projectState">
|
||||
<el-select
|
||||
v-model="formData.projectState"
|
||||
placeholder="请选择项目状态"
|
||||
class="full-width"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in statusList"
|
||||
:key="item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictValue"
|
||||
/>
|
||||
<el-select v-model="formData.projectState" placeholder="请选择项目状态" class="full-width">
|
||||
<el-option v-for="item in statusList" :key="item.dictValue" :label="item.dictLabel"
|
||||
:value="item.dictValue" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="预计人天" prop="budgetDate">
|
||||
<el-input
|
||||
v-model.number="formData.budgetDate"
|
||||
:min="0"
|
||||
:disabled="isEditing"
|
||||
class="full-width"
|
||||
/>
|
||||
<el-input v-model.number="formData.budgetDate" :min="0" :disabled="isEditing" class="full-width" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="开始日期" prop="startDate">
|
||||
<el-date-picker
|
||||
v-model="formData.startDate"
|
||||
type="date"
|
||||
placeholder="选择开始日期"
|
||||
format="yyyy-MM-dd"
|
||||
value-format="yyyy-MM-dd"
|
||||
class="full-width"
|
||||
:disabled="isEditing"
|
||||
/>
|
||||
<el-date-picker v-model="formData.startDate" type="date" placeholder="选择开始日期" format="yyyy-MM-dd"
|
||||
value-format="yyyy-MM-dd" class="full-width" :disabled="isEditing" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="结束日期" prop="endDate">
|
||||
<el-date-picker
|
||||
v-model="formData.endDate"
|
||||
type="date"
|
||||
placeholder="选择结束日期"
|
||||
format="yyyy-MM-dd"
|
||||
value-format="yyyy-MM-dd"
|
||||
class="full-width"
|
||||
:disabled="isEditing"
|
||||
/>
|
||||
<el-date-picker v-model="formData.endDate" type="date" placeholder="选择结束日期" format="yyyy-MM-dd"
|
||||
value-format="yyyy-MM-dd" class="full-width" :disabled="isEditing" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -121,165 +63,81 @@
|
|||
<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>
|
||||
<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 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
|
||||
type="primary"
|
||||
@click="saveProject"
|
||||
v-hasPermi="['project:detail:save']"
|
||||
>保存</el-button
|
||||
>
|
||||
<el-button type="primary" @click="saveProject" v-hasPermi="['project:detail:save']">保存</el-button>
|
||||
<el-button @click="cancelEdit">取消</el-button>
|
||||
</div>
|
||||
<div class="userBox">
|
||||
<div class="table-actions">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="addUser"
|
||||
v-hasPermi="['project:detail:addUser']"
|
||||
>新增成员</el-button
|
||||
>
|
||||
<el-button type="primary" @click="addUser" v-hasPermi="['project:detail:addUser']">新增成员</el-button>
|
||||
</div>
|
||||
<div class="f1">
|
||||
<CustomTable
|
||||
:columns="columns"
|
||||
:tableData="tableData"
|
||||
:show-selection="false"
|
||||
:show-index="true"
|
||||
:show-pagination="false"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
style="height: 100%"
|
||||
>
|
||||
<CustomTable :columns="columns" :tableData="tableData" :show-selection="false" :show-index="true"
|
||||
:show-pagination="false" @size-change="handleSizeChange" @current-change="handleCurrentChange"
|
||||
style="height: 100%">
|
||||
<template slot="userName" slot-scope="{ row }">
|
||||
<el-input
|
||||
v-if="row.isNew"
|
||||
v-model="row.userName"
|
||||
placeholder="选择人员"
|
||||
readonly
|
||||
@click.native="openSelectUser(row)"
|
||||
/>
|
||||
<el-input v-if="row.isNew" v-model="row.userName" placeholder="选择人员" readonly
|
||||
@click.native="openSelectUser(row)" />
|
||||
<span v-else>{{ row.userName }}</span>
|
||||
</template>
|
||||
<template slot="post" slot-scope="{ row }">
|
||||
<el-select
|
||||
v-if="
|
||||
(row.isEditing === true && row.teamId == row.teamId) ||
|
||||
row.isNew
|
||||
"
|
||||
v-model="row.postId"
|
||||
placeholder="请选择职位"
|
||||
>
|
||||
<el-option
|
||||
v-for="post in postOptions"
|
||||
:key="post.dictValue"
|
||||
:label="post.dictLabel"
|
||||
:value="post.dictValue"
|
||||
/>
|
||||
<el-select v-if="
|
||||
(row.isEditing === true && row.teamId == row.teamId) ||
|
||||
row.isNew
|
||||
" v-model="row.postId" placeholder="请选择职位">
|
||||
<el-option v-for="post in postOptions" :key="post.dictValue" :label="post.dictLabel"
|
||||
:value="post.dictValue" />
|
||||
</el-select>
|
||||
<span v-else>{{
|
||||
postOptions.find((post) => post.dictValue === row.postId)
|
||||
? postOptions.find((post) => post.dictValue === row.postId)
|
||||
.dictLabel
|
||||
.dictLabel
|
||||
: ""
|
||||
}}</span>
|
||||
</template>
|
||||
<template slot="operation" slot-scope="{ row }">
|
||||
<div class="operation-buttons">
|
||||
<template v-if="row.isNew">
|
||||
<el-button
|
||||
text
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="confirmAddUser(row)"
|
||||
>确认</el-button
|
||||
>
|
||||
<el-button
|
||||
text
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="cancelAddUser(row)"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button text type="text" size="mini" @click="confirmAddUser(row)">确认</el-button>
|
||||
<el-button text type="text" size="mini" @click="cancelAddUser(row)">取消</el-button>
|
||||
</template>
|
||||
<template v-else-if="row.isEditing && row.teamId == row.teamId">
|
||||
<el-button
|
||||
text
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="saveUserEdit(row)"
|
||||
>保存</el-button
|
||||
>
|
||||
<el-button
|
||||
text
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="cancelUserEdit(row)"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button text type="text" size="mini" @click="saveUserEdit(row)">保存</el-button>
|
||||
<el-button text type="text" size="mini" @click="cancelUserEdit(row)">取消</el-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
v-hasPermi="['project:detail:editUser']"
|
||||
@click="editUser(row)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
v-hasPermi="['project:detail:workLog']"
|
||||
@click="showTimesheet(row)"
|
||||
>工作日志</el-button
|
||||
>
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
v-hasPermi="['project:detail:deleteUser']"
|
||||
@click="confirmDelete(row)"
|
||||
>删除</el-button
|
||||
>
|
||||
<el-button type="text" size="mini" v-hasPermi="['project:detail:editUser']"
|
||||
@click="editUser(row)">编辑</el-button>
|
||||
<el-button type="text" size="mini" v-hasPermi="['project:detail:workLog']"
|
||||
@click="showTimesheet(row)">工作日志</el-button>
|
||||
<el-button type="text" size="mini" v-hasPermi="['project:detail:deleteUser']"
|
||||
@click="confirmDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -287,21 +145,12 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<SelectUser
|
||||
:dialogVisible="showSelectUser"
|
||||
:multi-select="false"
|
||||
:currentSelectedUser="currentSelectedUser"
|
||||
@confirm="handleUserConfirm"
|
||||
@close="closeSelectUser"
|
||||
/>
|
||||
<SelectUser :dialogVisible="showSelectUser" :multi-select="false" :currentSelectedUser="currentSelectedUser"
|
||||
@confirm="handleUserConfirm" @close="closeSelectUser" />
|
||||
|
||||
<SelectUser
|
||||
:dialogVisible="showProjectManagerSelect"
|
||||
:multi-select="false"
|
||||
:currentSelectedUser="projectManagerSelectedUser"
|
||||
@confirm="handleProjectManagerConfirm"
|
||||
@close="closeProjectManagerSelect"
|
||||
/>
|
||||
<SelectUser :dialogVisible="showProjectManagerSelect" :multi-select="false"
|
||||
:currentSelectedUser="projectManagerSelectedUser" @confirm="handleProjectManagerConfirm"
|
||||
@close="closeProjectManagerSelect" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -338,7 +187,7 @@ export default {
|
|||
budgetDate: 0,
|
||||
state: 0,
|
||||
dataState: 0,
|
||||
fileList:[]
|
||||
fileList: []
|
||||
},
|
||||
postOptions: [],
|
||||
statusList: [],
|
||||
|
@ -378,13 +227,14 @@ export default {
|
|||
{ required: true, message: "预算天数为必填", trigger: "blur" },
|
||||
],
|
||||
fileList: [
|
||||
{ required: true, message: "预算天数为必填", trigger: "blur" },
|
||||
{ required: true, message: "附件为必填", trigger: "blur" },
|
||||
],
|
||||
},
|
||||
filePng,
|
||||
zipPng,
|
||||
imagePng,
|
||||
token: getToken(),
|
||||
delFileArr: []
|
||||
|
||||
};
|
||||
},
|
||||
|
@ -450,6 +300,8 @@ export default {
|
|||
this.formData.projectId = res.data.projectId;
|
||||
this.formData.projectCode = res.data.projectCode;
|
||||
this.$modal.msgSuccess("操作成功");
|
||||
this.fetchProjectData()
|
||||
|
||||
} else {
|
||||
const hasLog = await projectApi.projectHasLogData({
|
||||
projectId: this.formData.projectId,
|
||||
|
@ -463,9 +315,22 @@ export default {
|
|||
)
|
||||
.then(async () => {
|
||||
await projectApi.updateProject(projectDataToSave);
|
||||
if (this.delFileArr.length) {
|
||||
await systemApi.delFileBatch(this.delFileArr.join(','))
|
||||
this.delFileArr = []
|
||||
|
||||
}
|
||||
this.fetchProjectData()
|
||||
|
||||
});
|
||||
} else {
|
||||
await projectApi.updateProject(projectDataToSave);
|
||||
if (this.delFileArr.length) {
|
||||
await systemApi.delFileBatch(this.delFileArr.join(','))
|
||||
this.delFileArr = []
|
||||
}
|
||||
this.fetchProjectData()
|
||||
|
||||
this.$modal.msgSuccess("操作成功");
|
||||
}
|
||||
}
|
||||
|
@ -568,11 +433,11 @@ export default {
|
|||
openProjectManagerSelect() {
|
||||
this.projectManagerSelectedUser = this.formData.projectLeader
|
||||
? [
|
||||
{
|
||||
userId: this.formData.projectLeader,
|
||||
nickName: this.formData.projectLeaderName,
|
||||
},
|
||||
]
|
||||
{
|
||||
userId: this.formData.projectLeader,
|
||||
nickName: this.formData.projectLeaderName,
|
||||
},
|
||||
]
|
||||
: [];
|
||||
this.showProjectManagerSelect = true;
|
||||
},
|
||||
|
@ -623,7 +488,7 @@ export default {
|
|||
},
|
||||
async fetchProjectData(id) {
|
||||
try {
|
||||
const response = await projectApi.getProjectDetail(id);
|
||||
const response = await projectApi.getProjectDetail(id||this.formData.projectId);
|
||||
const projectData = response.data;
|
||||
let {
|
||||
projectId,
|
||||
|
@ -693,9 +558,10 @@ export default {
|
|||
}
|
||||
},
|
||||
beforeUpload(file) {
|
||||
|
||||
this.fileLoading = true;
|
||||
if (file.size > 1024 * 1024 * 100) {
|
||||
this.fileLoading = false;
|
||||
this.fileLoading = false;
|
||||
|
||||
this.$message({
|
||||
type: "warning",
|
||||
|
@ -704,8 +570,8 @@ export default {
|
|||
return false;
|
||||
}
|
||||
},
|
||||
successUpload(res,file,fileList) {
|
||||
if(!fileList.filter((ele)=>ele.percentage!=100).length){
|
||||
successUpload(res, file, fileList) {
|
||||
if (!fileList.filter((ele) => ele.percentage != 100).length) {
|
||||
this.fileLoading = false;
|
||||
}
|
||||
if (res.code == 200) {
|
||||
|
@ -716,6 +582,7 @@ export default {
|
|||
fileUrl: res.url,
|
||||
});
|
||||
} else {
|
||||
this.fileLoading = false;
|
||||
this.$message({
|
||||
type: "error",
|
||||
message: res.msg,
|
||||
|
@ -729,48 +596,47 @@ export default {
|
|||
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: "删除成功!"
|
||||
})
|
||||
});
|
||||
this.delFileArr.push(row.id)
|
||||
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: "删除成功!"
|
||||
})
|
||||
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'
|
||||
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);
|
||||
|
@ -817,7 +683,8 @@ export default {
|
|||
}
|
||||
|
||||
.custom-form ::v-deep .el-form-item {
|
||||
margin-bottom: 25px; /* 增加表单行间距 */
|
||||
margin-bottom: 25px;
|
||||
/* 增加表单行间距 */
|
||||
}
|
||||
|
||||
.custom-form ::v-deep .el-form-item__content {
|
||||
|
@ -826,24 +693,29 @@ export default {
|
|||
}
|
||||
|
||||
.custom-form ::v-deep .el-input {
|
||||
height: 42px; /* 调高输入框高度 */
|
||||
height: 42px;
|
||||
/* 调高输入框高度 */
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
::v-deep .el-form-item__label {
|
||||
height: 42px; /* 调高输入框高度 */
|
||||
height: 42px;
|
||||
/* 调高输入框高度 */
|
||||
line-height: 42px;
|
||||
}
|
||||
|
||||
.custom-form ::v-deep .el-input__wrapper,
|
||||
.custom-form ::v-deep .el-date-editor.el-input,
|
||||
.custom-form ::v-deep .el-input-number {
|
||||
height: 42px; /* 调高输入框高度 */
|
||||
height: 42px;
|
||||
/* 调高输入框高度 */
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.custom-form ::v-deep .el-input__inner {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.custom-form ::v-deep .el-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -855,12 +727,14 @@ export default {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.userBox {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.table-actions {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
@ -927,13 +801,15 @@ export default {
|
|||
height: 64px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.fileRow {
|
||||
height: 38px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 10px;
|
||||
img{
|
||||
|
||||
img {
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
|
@ -942,12 +818,14 @@ export default {
|
|||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.fileItem{
|
||||
|
||||
.fileItem {
|
||||
gap: 10px;
|
||||
cursor: pointer;
|
||||
cursor: pointer;
|
||||
}
|
||||
.fileBox{
|
||||
max-height: 200px;
|
||||
|
||||
.fileBox {
|
||||
max-height: 136px;
|
||||
overflow: auto;
|
||||
padding-right: 10px;
|
||||
max-width: 90%;
|
||||
|
|
|
@ -237,6 +237,8 @@ export default {
|
|||
.selectBox span {
|
||||
width: 120px;
|
||||
}
|
||||
.content{
|
||||
|
||||
::v-deep .el-table {
|
||||
height: 100% !important;
|
||||
}
|
||||
|
@ -318,4 +320,6 @@ export default {
|
|||
::v-deep .el-table__footer td {
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -6,21 +6,14 @@
|
|||
{{ examineTask.taskName }}
|
||||
</div>
|
||||
<div class="flex-row jcfs f1" style="gap: 20px" v-if="isEdit">
|
||||
<el-button type="default" style="width: 90px" @click="saveScoreCheck(0)"
|
||||
>保存</el-button
|
||||
>
|
||||
<el-button type="primary" style="width: 90px" @click="saveScoreCheck(1)"
|
||||
>提交</el-button
|
||||
>
|
||||
<el-button type="default" style="width: 90px" @click="saveScoreCheck(0)">保存</el-button>
|
||||
<el-button type="primary" style="width: 90px" @click="saveScoreCheck(1)">提交</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-row jcsb aic userBox headerBox">
|
||||
<div class="flex-row aic" style="width: 200px;">
|
||||
<i
|
||||
class="el-icon-user-solid"
|
||||
style="color: #4096ff; font-size: 24px; margin-right: 5px"
|
||||
></i
|
||||
>{{ examineUser.userName }}
|
||||
<i class="el-icon-user-solid" style="color: #4096ff; font-size: 24px; margin-right: 5px"></i>{{
|
||||
examineUser.userName }}
|
||||
</div>
|
||||
<div class="totalBox aic" v-if="!isNormal">
|
||||
<div>考核评分:</div>
|
||||
|
@ -28,93 +21,64 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="tableBox">
|
||||
<div
|
||||
class="tableRow"
|
||||
v-for="(table, index) in tableData"
|
||||
:key="index"
|
||||
style="margin-bottom: 20px"
|
||||
>
|
||||
<div class="tableRow" v-for="(table, index) in tableData" :key="index" style="margin-bottom: 20px">
|
||||
<div class="userBox">{{ table[0].reviewCategory }}</div>
|
||||
<el-table :data="table" style="width: 100%">
|
||||
<el-table-column
|
||||
v-for="(header, hIndex) in headers"
|
||||
:key="hIndex"
|
||||
:label="header.label"
|
||||
:prop="header.prop"
|
||||
:width="header.width"
|
||||
:minWidth="header.minWidth"
|
||||
>
|
||||
<el-table-column v-for="(header, hIndex) in headers" :key="hIndex" :label="header.label" :prop="header.prop"
|
||||
:width="header.width" :minWidth="header.minWidth">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="评分"
|
||||
prop="score"
|
||||
:minWidth="isNormal ? 320 : 420"
|
||||
class-name="sorceTableCell"
|
||||
>
|
||||
<el-table-column class-name="editCell" label="员工自评" prop="score"
|
||||
v-if="!isNormal && examineTask.templateId && table[0].reviewCategory == '发展与协作' && examineTask.templateType != 0"
|
||||
min-width="220">
|
||||
<template slot-scope="scope">
|
||||
<div>
|
||||
<el-input type="textarea" :autosize="{ minRows: 4 }" placeholder="0/300" v-model="scope.row.remark"
|
||||
readonly maxlength="300" show-word-limit>
|
||||
</el-input>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="评分" prop="score"
|
||||
:minWidth="isNormal ? 320 : table[0].reviewCategory == '发展与协作' ? 220 : 420" class-name="sorceTableCell"
|
||||
v-if="(isNormal && table[0].reviewCategory != '发展与协作') || !isNormal">
|
||||
<template slot-scope="scope">
|
||||
<div style="width: 88%; position: relative">
|
||||
<div>
|
||||
<div
|
||||
class="flex-row jcsb"
|
||||
style="
|
||||
<div class="flex-row jcsb" style="
|
||||
margin-left: 10px;
|
||||
width: 90%;
|
||||
color: #999;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
"
|
||||
>
|
||||
">
|
||||
<div>0</div>
|
||||
<div v-show="scope.row.score != 10">10</div>
|
||||
</div>
|
||||
<div
|
||||
class="scoreText aic"
|
||||
v-show="scope.row.score != 0"
|
||||
:style="{
|
||||
left: scope.row.score * 9 - 5 + '%',
|
||||
}"
|
||||
>
|
||||
<img
|
||||
src="@/assets/task/score.png"
|
||||
:style="{
|
||||
height: '28px',
|
||||
width: '34px',
|
||||
zIndex: 0,
|
||||
position: 'absolute',
|
||||
top: '0',
|
||||
}"
|
||||
alt=""
|
||||
/>
|
||||
<div
|
||||
:style="{
|
||||
zIndex: 10,
|
||||
paddingLeft: scope.row.score != 10 ? '13px' : '9px',
|
||||
}"
|
||||
>
|
||||
<div class="scoreText aic" v-show="scope.row.score != 0" :style="{
|
||||
left: scope.row.score * 9 - 5 + '%',
|
||||
}">
|
||||
<img src="@/assets/task/score.png" :style="{
|
||||
height: '28px',
|
||||
width: '34px',
|
||||
zIndex: 0,
|
||||
position: 'absolute',
|
||||
top: '0',
|
||||
}" alt="" />
|
||||
<div :style="{
|
||||
zIndex: 10,
|
||||
paddingLeft: scope.row.score != 10 ? '13px' : '9px',
|
||||
}">
|
||||
{{ scope.row.score }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="item in scope.row.score == 0
|
||||
? 0
|
||||
: scope.row.score - 1"
|
||||
:key="item"
|
||||
class="stepBox"
|
||||
:style="{
|
||||
<div v-for="item in scope.row.score == 0
|
||||
? 0
|
||||
: scope.row.score - 1" :key="item" class="stepBox" :style="{
|
||||
left: item * 9 + 1.5 + '%',
|
||||
}"
|
||||
></div>
|
||||
<el-slider
|
||||
v-model="scope.row.score"
|
||||
:min="0"
|
||||
:max="10"
|
||||
@change="updateScore(scope.row)"
|
||||
:disabled="!isEdit"
|
||||
style="width: 90%"
|
||||
show-stops
|
||||
show-tooltip
|
||||
></el-slider>
|
||||
}"></div>
|
||||
<el-slider v-model="scope.row.score" :min="0" :max="10" @change="updateScore(scope.row)"
|
||||
:disabled="!isEdit" style="width: 90%" show-stops show-tooltip></el-slider>
|
||||
</div>
|
||||
<div class="statusText" v-show="scope.row.score == 0">
|
||||
暂未打分
|
||||
|
@ -122,49 +86,38 @@
|
|||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column class-name="editCell" label="自评总结" prop="score" v-if="isNormal" minWidth="140">
|
||||
<el-table-column class-name="editCell" label="自评总结" prop="score"
|
||||
v-if="(isNormal && examineTask.templateId && table[0].reviewCategory == '发展与协作') || (isNormal && !examineTask.templateId)"
|
||||
minWidth="140">
|
||||
<template slot-scope="scope">
|
||||
<div>
|
||||
<el-button
|
||||
v-if="isEdit"
|
||||
@click="handleEdit(scope.row)"
|
||||
type="text"
|
||||
size="mini"
|
||||
:class="{ hasEdit: !scope.row.remark }"
|
||||
style="font-weight: 600"
|
||||
>{{ scope.row.remark ? "查看" : "暂未评价" }}
|
||||
<i
|
||||
style="color: #4096ff; font-size: 14px"
|
||||
class="el-icon-edit el-icon--right"
|
||||
></i
|
||||
></el-button>
|
||||
<el-button
|
||||
v-if="!isEdit"
|
||||
@click="handleEdit(scope.row)"
|
||||
type="text"
|
||||
size="mini"
|
||||
:class="{ hasEdit: !scope.row.remark }"
|
||||
style="font-weight: 600"
|
||||
>{{ scope.row.remark ? "查看" : "暂未评价" }}</el-button
|
||||
>
|
||||
<el-button v-if="isEdit" @click="handleEdit(scope.row)" type="text" size="mini"
|
||||
:class="{ hasEdit: !scope.row.remark }" style="font-weight: 600">{{ scope.row.remark ? "查看" : "暂未评价"
|
||||
}}
|
||||
<i style="color: #4096ff; font-size: 14px" class="el-icon-edit el-icon--right"></i></el-button>
|
||||
<el-button v-if="!isEdit" @click="handleEdit(scope.row)" type="text" size="mini"
|
||||
:class="{ hasEdit: !scope.row.remark }" style="font-weight: 600">{{ scope.row.remark ? "查看" : "暂未评价"
|
||||
}}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-if="examineTask.templateType != 0 && isNormal && table[0].reviewCategory != '发展与协作'"
|
||||
style="margin-top: 10px;">
|
||||
<div class="userBox">评价</div>
|
||||
<div>
|
||||
<el-input type="textarea" :autosize="{ minRows: 4 }" placeholder="0/300" v-model="table[0].remarkCate"
|
||||
:readonly="!isEdit" maxlength="300" show-word-limit>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div v-if="!isNormal">
|
||||
<div v-if="(isNormal && examineTask.templateType == 0) || (!isNormal)">
|
||||
<div class="userBox">总体评价</div>
|
||||
<div>
|
||||
<el-input
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 4 }"
|
||||
placeholder="0/300"
|
||||
v-model="saveData.judgeContent"
|
||||
:readonly="!isEdit"
|
||||
maxlength="300"
|
||||
show-word-limit
|
||||
>
|
||||
<el-input type="textarea" :autosize="{ minRows: 4 }" placeholder="0/300" v-model="saveData.judgeContent"
|
||||
:readonly="!isEdit" maxlength="300" show-word-limit>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -173,25 +126,16 @@
|
|||
|
||||
<el-dialog title="自评总结" :visible.sync="dialogVisible" width="30%">
|
||||
<div>
|
||||
<el-input
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 4 }"
|
||||
placeholder="0/200"
|
||||
v-model="remark"
|
||||
:readonly="!isEdit"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
>
|
||||
<el-input type="textarea" :autosize="{ minRows: 4 }" placeholder="0/200" v-model="remark" :readonly="!isEdit"
|
||||
maxlength="200" show-word-limit>
|
||||
</el-input>
|
||||
</div>
|
||||
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancelEdit">{{
|
||||
isEdit ? "取 消" : "关闭"
|
||||
}}</el-button>
|
||||
<el-button type="primary" @click="saveEdit" v-if="isEdit"
|
||||
>确 定</el-button
|
||||
>
|
||||
}}</el-button>
|
||||
<el-button type="primary" @click="saveEdit" v-if="isEdit">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
@ -215,7 +159,7 @@ export default {
|
|||
{
|
||||
label: "评分标准",
|
||||
prop: "remarks",
|
||||
minWidth:this.$route.query.isNormal? 240:360,
|
||||
minWidth: this.$route.query.isNormal ? 240 : 360,
|
||||
},
|
||||
],
|
||||
// 二维数组,每个子数组代表一个表格的数据
|
||||
|
@ -312,7 +256,10 @@ export default {
|
|||
score: ele.score,
|
||||
configId: ele.id,
|
||||
remark: ele.remark,
|
||||
reviewCategory: ele.reviewCategory,
|
||||
}));
|
||||
this.saveData.examineRemarkList = this.tableData.filter((ele)=>ele[0].reviewCategory!='发展与协作').map((ele) => ({ reviewCategory: ele[0].reviewCategory, remark: ele[0].remarkCate }))
|
||||
|
||||
this.saveData.taskId = this.examineTaskId;
|
||||
this.saveData.examineId = this.examineId;
|
||||
},
|
||||
|
@ -326,21 +273,21 @@ export default {
|
|||
return;
|
||||
}
|
||||
// 提交
|
||||
if (this.saveData.examineDetailList.filter((ele) => !ele.score).length) {
|
||||
if (this.saveData.examineDetailList.filter((ele) => !ele.score && ele.reviewCategory != '发展与协作' || (!ele.score && !this.isNormal)).length) {
|
||||
this.$alert("存在未评分绩效项,请完善后再试", "提交失败", {
|
||||
confirmButtonText: "确定",
|
||||
type: "warning",
|
||||
});
|
||||
} else if (
|
||||
this.saveData.examineDetailList.filter((ele) => !ele.remark).length &&
|
||||
this.saveData.examineDetailList.filter((ele) => !ele.remark && ele.reviewCategory == '发展与协作').length &&
|
||||
this.isNormal &&
|
||||
status
|
||||
) {
|
||||
this.$alert("自评总结为必填,请完善后再试", "提交失败", {
|
||||
this.$alert("发展与协作下的自评总结为必填,请完善后再试", "提交失败", {
|
||||
confirmButtonText: "确定",
|
||||
type: "warning",
|
||||
});
|
||||
} else if (this.saveData.judgeContent.length > 300 && !this.isNormal) {
|
||||
} else if (this.saveData.judgeContent.length > 300 && !this.isNormal && this.examineTask.templateType == '0') {
|
||||
this.$message({
|
||||
message: "总体评价限制300个字符",
|
||||
type: "warning",
|
||||
|
@ -350,6 +297,11 @@ export default {
|
|||
message: "总体评价为必填",
|
||||
type: "warning",
|
||||
});
|
||||
} else if (this.saveData.examineRemarkList.filter((ele) => !ele.remark).length && this.isNormal) {
|
||||
this.$message({
|
||||
message: "存在未填写大类评价,请完善后再试",
|
||||
type: "warning",
|
||||
});
|
||||
} else {
|
||||
if (status) {
|
||||
this.$confirm(
|
||||
|
@ -400,9 +352,11 @@ export default {
|
|||
.conetentBox {
|
||||
padding: 40px 30px 30px;
|
||||
background-color: #fff;
|
||||
height: 90vh; /* 设置整体高度 */
|
||||
height: 90vh;
|
||||
/* 设置整体高度 */
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
@ -412,31 +366,37 @@ export default {
|
|||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
::v-deep .el-slider__runway {
|
||||
height: 14px;
|
||||
border-radius: 10px;
|
||||
margin: 10px !important;
|
||||
/* width: 95%; */
|
||||
}
|
||||
|
||||
::v-deep .el-slider__runway.disabled .el-slider__bar {
|
||||
height: 14px;
|
||||
border-radius: 10px;
|
||||
|
||||
background-color: #ff5722;
|
||||
}
|
||||
|
||||
::v-deep .el-slider__stop {
|
||||
height: 14px;
|
||||
border-radius: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
::v-deep .el-slider__bar {
|
||||
height: 14px;
|
||||
border-radius: 10px;
|
||||
background: linear-gradient(to right, #ffb144, #ff7d00);
|
||||
}
|
||||
|
||||
::v-deep .el-slider__button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.scoreText {
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
|
@ -445,6 +405,7 @@ export default {
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
::v-deep .el-table th {
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
|
@ -456,6 +417,7 @@ export default {
|
|||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.statusText {
|
||||
color: #ff7d00;
|
||||
position: absolute;
|
||||
|
@ -464,43 +426,52 @@ export default {
|
|||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.hasEdit {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
::v-deep .el-dialog {
|
||||
margin-top: 15% !important;
|
||||
}
|
||||
|
||||
.tableBox {
|
||||
height: 75%;
|
||||
overflow: auto;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.tableBox ::v-deep .el-table {
|
||||
border-left: 1px solid #eeeeee;
|
||||
border-right: 1px solid #eeeeee;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
padding: 20px;
|
||||
box-shadow: 0 0 20px #0000000f;
|
||||
}
|
||||
|
||||
.titleBox {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.headerBox {
|
||||
padding: 20px;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 2px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.block {
|
||||
width: 4px;
|
||||
height: 24px;
|
||||
background-color: #4096ff;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.stepBox {
|
||||
position: absolute;
|
||||
top: 33px;
|
||||
|
@ -509,6 +480,7 @@ export default {
|
|||
background-color: #fff;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.totalBox {
|
||||
width: 180px;
|
||||
display: flex;
|
||||
|
@ -516,28 +488,35 @@ export default {
|
|||
font-size: 16px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.scoreTotal {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: #ff7d00;
|
||||
}
|
||||
|
||||
::v-deep .el-table__body .sorceTableCell .cell {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
::v-deep .sorceTableCell.el-table__cell{
|
||||
padding-right: 10px !important;
|
||||
|
||||
::v-deep .sorceTableCell.el-table__cell {
|
||||
padding-right: 10px !important;
|
||||
}
|
||||
|
||||
::v-deep .el-table__body .el-table__cell {
|
||||
padding: 20px 40px;
|
||||
}
|
||||
|
||||
::v-deep .el-table__header .el-table__cell {
|
||||
padding: 14px 30px;
|
||||
|
||||
}
|
||||
::v-deep .el-table__header .el-table__cell .cell{
|
||||
|
||||
::v-deep .el-table__header .el-table__cell .cell {
|
||||
padding-left: 20px !important;
|
||||
}
|
||||
::v-deep .editCell{
|
||||
|
||||
::v-deep .editCell {
|
||||
padding-right: 20px !important;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,493 @@
|
|||
<template>
|
||||
<div class="appraisal-manager ">
|
||||
|
||||
<div class="flex-row aic" style="gap: 20px;margin-bottom: 20px;">
|
||||
<div>看板名称</div>
|
||||
<div>
|
||||
<el-input v-model="moduleName" class="filter-input" readonly>
|
||||
</el-input>
|
||||
</div>
|
||||
<div>看板类型</div>
|
||||
|
||||
<el-select v-model="moduleType" placeholder="看板类型" clearable style="width: 200px" readonly>
|
||||
<el-option label="年度考核" value="0" />
|
||||
<el-option label="季度考核" value="1" />
|
||||
<el-option label="年月考核" value="2" />
|
||||
</el-select>
|
||||
|
||||
</div>
|
||||
<div class="modal">
|
||||
<div class="left">
|
||||
<div class="setText" style="font-weight: 600">累计权重</div>
|
||||
<el-collapse v-model="letfValue" :accordion="true" style="height: 300px; overflow: auto"
|
||||
@change="showAllScoure">
|
||||
<el-collapse-item v-for="(item, index) in scoreList" :key="index" :name="item.title">
|
||||
<template #title>
|
||||
<div class="jcsb flex-row contentTitle">
|
||||
<span class="setTitle">{{ item.title }}</span>
|
||||
<span class="statusText">{{ item.weight }}%</span>
|
||||
</div>
|
||||
</template>
|
||||
<div>
|
||||
<div v-for="(ele, index) in item.list" :key="index" class="flex-row jcsb leftSub" :class="{
|
||||
selectClass: selectLeftRow == ele.title + ele.type,
|
||||
}" @click="selectLeft(ele)">
|
||||
<div>{{ ele.title }}</div>
|
||||
<div class="statusText">{{ ele.weight }}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
<div class="flex-row jcsb" style="margin-top: 20px; padding-right: 15px">
|
||||
<div class="setTitle" style="font-weight: 600">总计</div>
|
||||
<div class="statusText">
|
||||
{{
|
||||
scoreList.reduce((total, ele) => total + (ele.weight || 0), 0)
|
||||
}}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div v-show="leftType !== '组长评估绩效指标' && leftType !== '个人自评绩效指标'">
|
||||
<div class="flex-row jcsb setHeader">
|
||||
<div style="width: 15%; font-weight: 600">考核项</div>
|
||||
<div style="width: 50%; font-weight: 600;text-align: center;">评分标准</div>
|
||||
<div class="center" style="width: 25%; font-weight: 600">
|
||||
权重占比
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="(item, index) in (
|
||||
(
|
||||
(scoreList.find((ele) => ele.title == letfValue) || {})
|
||||
.list || []
|
||||
).find((ele) => ele.title + ele.type == selectLeftRow) || {}
|
||||
).rightArr || []" :key="index" class="flex-row jcsb aic contentRow">
|
||||
<div style="width: 15%; font-weight: 500">
|
||||
{{ item.reviewItem }}
|
||||
</div>
|
||||
<div class="center" style="width: 50%;padding: 0 20px;">
|
||||
{{ item.remarks }}
|
||||
</div>
|
||||
<div class="center" style="width: 25%">
|
||||
<div class="flex-row jcsb" style="
|
||||
margin-left: 10px;
|
||||
width: 100%;
|
||||
color: #999;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
">
|
||||
<div>0</div>
|
||||
<div v-show="item.weight != 20">20</div>
|
||||
</div>
|
||||
<div class="scoreText aic" v-show="item.weight != 0" :style="{
|
||||
left: item.weight * 4.5 - 2.5 + '%',
|
||||
}">
|
||||
<img src="@/assets/task/score.png" :style="{
|
||||
height: '28px',
|
||||
width: '34px',
|
||||
zIndex: 0,
|
||||
position: 'absolute',
|
||||
top: '-2px',
|
||||
}" alt="" />
|
||||
<div :style="{
|
||||
zIndex: 10,
|
||||
textIndent: item.weight < 10 ? '13px' : '10px',
|
||||
fontSize: '12px',
|
||||
}">
|
||||
{{ item.weight }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="flex-row jcsb scoreBox" style="margin-left: 15px">
|
||||
<div>0%</div>
|
||||
<div class="scoreText">{{ item.weight }}%</div>
|
||||
<div>20%</div>
|
||||
</div> -->
|
||||
<div v-for="item in item.weight == 0 ? 0 : item.weight - 1" :key="item" class="stepBox"
|
||||
:style="{
|
||||
left: item * 5 + 4 + '%',
|
||||
}"></div>
|
||||
<el-slider :disabled="isDisabled" v-model="item.weight" :max="20"
|
||||
@change="changeTotal"></el-slider>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="leftType == '组长评估绩效指标' || leftType == '个人自评绩效指标'">
|
||||
<div v-for="(ele, index) in
|
||||
(scoreList.find((ele) => ele.title == leftType) || {})
|
||||
.list || []
|
||||
|
||||
" :key="index">
|
||||
<div style="margin: 10px;font-weight: 600;font-size: 18px;">{{ ele.title }}</div>
|
||||
<div class="flex-row jcsb setHeader">
|
||||
<div style="width: 15%; font-weight: 600">考核项</div>
|
||||
<div style="width: 50%; font-weight: 600;text-align: center;">评分标准</div>
|
||||
<div class="center" style="width: 25%; font-weight: 600">
|
||||
权重占比
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-bottom: 50px;">
|
||||
<div v-for="(item, index) in (ele.rightArr || [])" class="flex-row jcsb aic contentRow">
|
||||
<div style="width: 15%; font-weight: 600">
|
||||
{{ item.reviewItem }}
|
||||
</div>
|
||||
<div class="center" style="width: 50%;padding: 0 20px;">
|
||||
{{ item.remarks }}
|
||||
</div>
|
||||
<div class="center" style="width: 25%">
|
||||
<div class="flex-row jcsb" style="
|
||||
margin-left: 10px;
|
||||
width: 100%;
|
||||
color: #999;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
">
|
||||
<div>0</div>
|
||||
<div v-show="item.weight != 20">20</div>
|
||||
</div>
|
||||
<div class="scoreText aic" v-show="item.weight != 0" :style="{
|
||||
left: item.weight * 4.5 - 2.5 + '%',
|
||||
}">
|
||||
<img src="@/assets/task/score.png" :style="{
|
||||
height: '28px',
|
||||
width: '34px',
|
||||
zIndex: 0,
|
||||
position: 'absolute',
|
||||
top: '-2px',
|
||||
}" alt="" />
|
||||
<div :style="{
|
||||
zIndex: 10,
|
||||
textIndent: item.weight < 10 ? '13px' : '10px',
|
||||
fontSize: '12px',
|
||||
}">
|
||||
{{ item.weight }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-for="item in item.weight == 0 ? 0 : item.weight - 1" :key="item"
|
||||
class="stepBox" :style="{
|
||||
left: item * 5 + 4 + '%',
|
||||
}"></div>
|
||||
<el-slider :disabled="isDisabled" v-model="item.weight" :max="20"
|
||||
@change="changeTotal"></el-slider>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { taskApi } from "@/utils/api";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
moduleId: '',
|
||||
moduleName: '',
|
||||
moduleType: '',
|
||||
scoreList: [],
|
||||
letfValue: "",
|
||||
selectLeftRow: '',
|
||||
leftType: '',
|
||||
isDisabled: true
|
||||
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
getDetail() {
|
||||
taskApi.getTaskModelSet(this.moduleId).then((res) => {
|
||||
let objData = {};
|
||||
res.data.forEach((ele) => {
|
||||
if (!objData[ele.reviewType]) objData[ele.reviewType] = [];
|
||||
objData[ele.reviewType].push(ele);
|
||||
});
|
||||
let arrList = {};
|
||||
Object.keys(objData).forEach((ele) => {
|
||||
let arr = [];
|
||||
objData[ele].forEach((item) => {
|
||||
if (!arr[item.reviewCategory]) arr[item.reviewCategory] = [];
|
||||
arr[item.reviewCategory].push(item);
|
||||
});
|
||||
arrList[ele] = arr;
|
||||
});
|
||||
|
||||
this.scoreList = [
|
||||
{
|
||||
title: "组长评估绩效指标",
|
||||
list: Object.keys(arrList["0"]).map((ele) => ({
|
||||
title: ele,
|
||||
weight: arrList["0"][ele].reduce(
|
||||
(total, item) => (item.weight || 0) + total,
|
||||
0
|
||||
),
|
||||
rightArr: arrList["0"][ele],
|
||||
type: 0,
|
||||
})),
|
||||
weight: Object.values(arrList["0"]).reduce(
|
||||
(total, item) =>
|
||||
(item.reduce((total, item) => (item.weight || 0) + total, 0) ||
|
||||
0) + total,
|
||||
0
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "个人自评绩效指标",
|
||||
list: Object.keys(arrList["1"]).map((ele) => ({
|
||||
title: ele,
|
||||
weight: arrList["1"][ele].reduce(
|
||||
(total, item) => (item.weight || 0) + total,
|
||||
0
|
||||
),
|
||||
rightArr: arrList["1"][ele],
|
||||
type: 1,
|
||||
})),
|
||||
weight: Object.values(arrList["1"]).reduce(
|
||||
(total, item) =>
|
||||
(item.reduce((total, item) => (item.weight || 0) + total, 0) ||
|
||||
0) + total,
|
||||
0
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "系统核算绩效指标",
|
||||
list: Object.keys(arrList["2"] || {}).map((ele) => ({
|
||||
title: ele,
|
||||
weight: arrList["2"][ele].reduce(
|
||||
(total, item) => (item.weight || 0) + total,
|
||||
0
|
||||
),
|
||||
rightArr: arrList["2"][ele],
|
||||
type: 2,
|
||||
})),
|
||||
weight: Object.values(arrList["2"] || {}).reduce(
|
||||
(total, item) =>
|
||||
(item.reduce((total, item) => (item.weight || 0) + total, 0) ||
|
||||
0) + total,
|
||||
0
|
||||
),
|
||||
},
|
||||
];
|
||||
if (!arrList["2"]) {
|
||||
this.scoreList.length = 2
|
||||
}
|
||||
|
||||
this.dialogVisible2 = true;
|
||||
});
|
||||
},
|
||||
selectLeft(row) {
|
||||
this.leftType = ''
|
||||
this.selectLeftRow = row.title + row.type;
|
||||
},
|
||||
changeTotal(data) {
|
||||
this.$nextTick(() => {
|
||||
this.scoreList.forEach((ele) => {
|
||||
ele.list.forEach((item) => {
|
||||
item.weight = item.rightArr.reduce(
|
||||
(total, ele) => total + (ele.weight || 0),
|
||||
0
|
||||
);
|
||||
});
|
||||
ele.weight = ele.list.reduce(
|
||||
(total, ele) => total + (ele.weight || 0),
|
||||
0
|
||||
);
|
||||
});
|
||||
});
|
||||
},
|
||||
showAllScoure(val) {
|
||||
if (val)
|
||||
this.leftType = val
|
||||
else {
|
||||
this.leftType = parseInt(this.selectLeftRow)==0?'组长评估绩效指标':'个人自评绩效指标'
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.moduleId = this.$route.query.id
|
||||
this.moduleName = this.$route.query.moduleName
|
||||
this.moduleType = this.$route.query.moduleType
|
||||
this.getDetail()
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.appraisal-manager {
|
||||
padding: 30px;
|
||||
background-color: #fff;
|
||||
height: calc(100vh - 100px);
|
||||
/* 设置整体高度 */
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: flex;
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-top: 1px solid #ccc;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 20%;
|
||||
padding: 20px;
|
||||
border-right: 1px solid #ccc;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 80%;
|
||||
padding: 20px 40px;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
|
||||
div.center {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.scoreBox {
|
||||
position: absolute;
|
||||
top: 45px;
|
||||
right: -20px;
|
||||
}
|
||||
|
||||
::v-deep .el-slider__runway {
|
||||
height: 14px;
|
||||
border-radius: 10px;
|
||||
margin: 10px !important;
|
||||
/* width: 95%; */
|
||||
}
|
||||
|
||||
::v-deep .el-slider__runway.disabled .el-slider__bar {
|
||||
height: 14px;
|
||||
border-radius: 10px;
|
||||
|
||||
background-color: #ff5722;
|
||||
}
|
||||
|
||||
::v-deep .el-slider__stop {
|
||||
height: 14px;
|
||||
border-radius: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
::v-deep .el-slider__bar {
|
||||
height: 14px;
|
||||
border-radius: 10px;
|
||||
background: linear-gradient(to right, #ffb144, #ff7d00);
|
||||
}
|
||||
|
||||
::v-deep .el-slider__button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.scoreText {
|
||||
color: #1686d8;
|
||||
}
|
||||
|
||||
.setText {
|
||||
margin-bottom: 20px;
|
||||
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.leftSub {
|
||||
padding: 10px 20px 10px 10px;
|
||||
margin-bottom: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.setTitle {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
::v-deep .el-collapse-item__content {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
::v-deep .el-collapse-item__header {}
|
||||
|
||||
.contentTitle {}
|
||||
|
||||
.statusText {
|
||||
color: #ff5722;
|
||||
}
|
||||
|
||||
::v-deep .el-collapse {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.search-buttons ::v-deep .el-button {
|
||||
width: 90px !important;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
::v-deep .operation-buttons .el-button {
|
||||
padding: 4px 8px;
|
||||
margin: 0 2px;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.selectClass {
|
||||
background-color: #4096ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.scoreText {
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.block {
|
||||
width: 4px;
|
||||
height: 24px;
|
||||
background-color: #4096ff;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.stepBox {
|
||||
position: absolute;
|
||||
top: 29px;
|
||||
height: 14px;
|
||||
width: 2px;
|
||||
background-color: #fff;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.totalBox {
|
||||
width: 150px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.contentRow {
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.setHeader {
|
||||
background-color: #f8f8f9;
|
||||
padding: 15px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,492 @@
|
|||
<template>
|
||||
<div class="project-list">
|
||||
<div class="search-bar">
|
||||
<el-form :inline="true" :model="searchForm" class="demo-form-inline" size="small">
|
||||
<el-form-item label="看板名称" class="form-item">
|
||||
<el-input v-model="searchForm.templateName" placeholder="看板名称" style="width: 300px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建人" class="form-item">
|
||||
<el-input v-model="searchForm.createByName" placeholder="创建人" readonly
|
||||
@click.native="openUserSelectDialog"><el-button slot="append"
|
||||
icon="el-icon-s-custom"></el-button></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="考核类型" class="form-item">
|
||||
<el-select v-model="searchForm.templateType" placeholder="状态" clearable style="width: 300px">
|
||||
<el-option label="年度考核" value="0" />
|
||||
<el-option label="季度考核" value="1" />
|
||||
<el-option label="年月考核" value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="search-buttons">
|
||||
<el-button type="primary" @click="onSearch">查询</el-button>
|
||||
<el-button @click="onReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<!-- <div class="table-actions mb10">
|
||||
<el-button type="primary" size="mini" @click="addTask" style="height: 36px">+ 新增看板</el-button>
|
||||
</div> -->
|
||||
<div class="f1 df">
|
||||
<CustomTable :columns="columns" :tableData="tableData" :total="total" :show-selection="false"
|
||||
:show-index="true" @size-change="handleSizeChange" @current-change="handleCurrentChange"
|
||||
tableHeight="495px">
|
||||
<template slot="operation" slot-scope="{ row }">
|
||||
<div class="operation-buttons">
|
||||
<el-button type="text" size="mini" @click="viewDetail(row)">看板详情</el-button>
|
||||
<!-- <el-button @click="viewDetail(row)" type="text" size="mini">编辑</el-button> -->
|
||||
<el-button type="text" size="mini" @click="delTask(row)">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</CustomTable>
|
||||
</div>
|
||||
<SelectUser :dialogVisible="userSelectDialogVisible" :currentSelectedUser="currentSelectedUser"
|
||||
:currentSelectedUserName="currentSelectedUserName" :highligt="true" ref="selectUserRef"
|
||||
@confirm="handleUserConfirm" @close="handleUserClose" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CustomTable from "@/components/CustomTable.vue";
|
||||
import SelectUser from "@/components/SelectUser.vue";
|
||||
import { taskApi } from "@/utils/api";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CustomTable,
|
||||
SelectUser,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
searchForm: {
|
||||
templateName: "",
|
||||
templateType: "",
|
||||
createBy: "",
|
||||
createByName: ''
|
||||
},
|
||||
columns: [
|
||||
{ prop: "templateName", label: "看板名称" },
|
||||
{
|
||||
prop: "templateType", label: "考核类型", type: "status",
|
||||
callback: (value) => {
|
||||
if (value == 0) var type = "年度考核";
|
||||
else if (value == 1) var type = "季度考核";
|
||||
else if (value == 2) var type = "月度考核";
|
||||
return type
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
prop: "createByName",
|
||||
label: "创建人",
|
||||
},
|
||||
{
|
||||
prop: "createTime",
|
||||
label: "创建日期",
|
||||
|
||||
},
|
||||
{
|
||||
prop: "operation",
|
||||
label: "操作",
|
||||
width: "250",
|
||||
className: "operation-column",
|
||||
},
|
||||
],
|
||||
tableData: [],
|
||||
total: 0,
|
||||
userSelectDialogVisible: false,
|
||||
currentSelectedUser: [],
|
||||
currentSelectedUserName: [],
|
||||
pageNum: 1, // 当前页码
|
||||
pageSize: 10, // 每页条数
|
||||
statusList: [
|
||||
{ label: "全部", value: "" },
|
||||
{ label: "进行中", value: "0" },
|
||||
{ label: "已过期", value: "2" },
|
||||
],
|
||||
dialogVisible1: false,
|
||||
isEdit: false,
|
||||
taskData: {
|
||||
id: "",
|
||||
taskName: "",
|
||||
peopleNumberDetail: "",
|
||||
userIdList: [],
|
||||
endTime: "",
|
||||
peopleNumber: 0,
|
||||
year: "",
|
||||
},
|
||||
rules: {
|
||||
taskName: [
|
||||
{ required: true, message: "请输入活动名称", trigger: "blur" },
|
||||
{ min: 1, max: 20, message: "长度限制20个字符", trigger: "blur" },
|
||||
],
|
||||
peopleNumberDetail: [
|
||||
{ required: true, message: "请选择考核人员", trigger: "change" },
|
||||
],
|
||||
endTime: [
|
||||
{ required: true, message: "请选择截止时间", trigger: "blur" },
|
||||
],
|
||||
year: [{ required: true, message: "请选择年份", trigger: "blur" }],
|
||||
},
|
||||
dialogVisible2: false,
|
||||
letfValue: "",
|
||||
scoreList: [],
|
||||
modelList: [],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
dialogVisible1(newVal) {
|
||||
if (newVal) {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.selectUserRef?.$refs.customTableRef?.handleCurrentChange(
|
||||
1
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onSearch() {
|
||||
this.getTaskModelList();
|
||||
},
|
||||
onReset() {
|
||||
Object.keys(this.searchForm).forEach((key) => {
|
||||
this.searchForm[key] = "";
|
||||
});
|
||||
this.getTaskModelList();
|
||||
},
|
||||
getTaskModelList() {
|
||||
taskApi
|
||||
.getTaskModel({
|
||||
...this.searchForm,
|
||||
pageNum: this.pageNum,
|
||||
pageSize: this.pageSize,
|
||||
})
|
||||
.then((res) => {
|
||||
this.tableData = res.rows;
|
||||
this.total = res.total;
|
||||
});
|
||||
},
|
||||
handleSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.pageNum = 1; // 重置为第一页
|
||||
this.getTaskModelList();
|
||||
},
|
||||
handleCurrentChange(page) {
|
||||
this.pageNum = page;
|
||||
this.getTaskModelList();
|
||||
},
|
||||
openUserSelectDialog() {
|
||||
this.userSelectDialogVisible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.selectUserRef?.$refs.customTableRef?.clearSelection();
|
||||
this.currentSelectedUser = [this.searchForm.createBy];
|
||||
this.currentSelectedUserName = [this.searchForm.createName];
|
||||
|
||||
});
|
||||
},
|
||||
handleUserConfirm(data) {
|
||||
this.searchForm.createByName = data[0].nickName;
|
||||
this.searchForm.createBy = data[0].userId;
|
||||
},
|
||||
handleUserClose() {
|
||||
this.userSelectDialogVisible = false;
|
||||
},
|
||||
addTask() {
|
||||
this.isEdit = false;
|
||||
this.dialogVisible1 = true;
|
||||
this.taskData = {
|
||||
id: "",
|
||||
taskName: "",
|
||||
peopleNumberDetail: "",
|
||||
userIdList: [],
|
||||
endTime: "",
|
||||
peopleNumber: 0,
|
||||
};
|
||||
},
|
||||
viewDetail(row) {
|
||||
this.$router.push({
|
||||
path: `/workAppraisal/moduleDetail?id=${row.id}&moduleName=${row.templateName}&moduleType=${row.templateType}`
|
||||
})
|
||||
},
|
||||
delTask(row) {
|
||||
this.$confirm(
|
||||
"是否确认删除该条看板",
|
||||
"确认删除",
|
||||
{
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
}
|
||||
).then(() => {
|
||||
taskApi.delTaskModule(row.id).then((res) => {
|
||||
this.$message({
|
||||
type: "success",
|
||||
message: "删除成功!",
|
||||
});
|
||||
this.getTaskModelList();
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getTaskModelList();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.project-list {
|
||||
padding: 20px;
|
||||
background-color: white;
|
||||
height: 88vh;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.demo-form-inline {
|
||||
// display: flex;
|
||||
// flex-wrap: nowrap;
|
||||
// align-items: flex-start;
|
||||
}
|
||||
|
||||
.demo-form-inline .el-form-item {
|
||||
// margin-right: 50px; /* 将间距设置为 30px */
|
||||
// margin-bottom: 0;
|
||||
}
|
||||
|
||||
.demo-form-inline .el-form-item:last-child {
|
||||
margin-right: 0;
|
||||
/* 移除最后一个元素的右边距 */
|
||||
}
|
||||
|
||||
.form-item {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.form-item ::v-deep .el-form-item__content {
|
||||
// width: 100%;
|
||||
}
|
||||
|
||||
.form-item ::v-deep .el-input,
|
||||
.form-item ::v-deep .el-select {
|
||||
// width: 100%;
|
||||
}
|
||||
|
||||
.search-buttons {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
::v-deep .operation-buttons .el-button {
|
||||
padding: 4px 8px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
::v-deep .operation-column {
|
||||
background-color: #ffffff;
|
||||
box-shadow: -2px 0 5px rgba(241, 112, 6, 0.1);
|
||||
}
|
||||
|
||||
.el-button.is-text {
|
||||
min-width: 32px !important;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dialog-footer .el-button {
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.delete-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.warning-icon {
|
||||
font-size: 24px;
|
||||
color: #e6a23c;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
/* 添加以下样式来使对话框垂直居中 */
|
||||
::v-deep .delete-dialog.el-dialog {
|
||||
margin-top: 0 !important;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
::v-deep .el-table th {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
::v-deep .el-table .cell {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
::v-deep .el-dialog {
|
||||
margin-top: 10% !important;
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: flex;
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 40%;
|
||||
padding: 20px;
|
||||
border-right: 1px solid #ccc;
|
||||
height: 450px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 60%;
|
||||
padding: 20px 40px;
|
||||
height: 450px;
|
||||
overflow: auto;
|
||||
|
||||
div.center {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.scoreBox {
|
||||
position: absolute;
|
||||
top: 45px;
|
||||
right: -20px;
|
||||
}
|
||||
|
||||
::v-deep .el-slider__runway {
|
||||
height: 14px;
|
||||
border-radius: 10px;
|
||||
margin: 10px !important;
|
||||
/* width: 95%; */
|
||||
}
|
||||
|
||||
::v-deep .el-slider__runway.disabled .el-slider__bar {
|
||||
height: 14px;
|
||||
border-radius: 10px;
|
||||
|
||||
background-color: #ff5722;
|
||||
}
|
||||
|
||||
::v-deep .el-slider__stop {
|
||||
height: 14px;
|
||||
border-radius: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
::v-deep .el-slider__bar {
|
||||
height: 14px;
|
||||
border-radius: 10px;
|
||||
background: linear-gradient(to right, #ffb144, #ff7d00);
|
||||
}
|
||||
|
||||
::v-deep .el-slider__button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.scoreText {
|
||||
color: #1686d8;
|
||||
}
|
||||
|
||||
.setText {
|
||||
margin-bottom: 20px;
|
||||
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.leftSub {
|
||||
padding: 10px 20px 10px 10px;
|
||||
margin-bottom: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.setTitle {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
::v-deep .el-collapse-item__content {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
::v-deep .el-collapse-item__header {}
|
||||
|
||||
.contentTitle {}
|
||||
|
||||
.statusText {
|
||||
color: #ff5722;
|
||||
}
|
||||
|
||||
::v-deep .el-collapse {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.search-buttons ::v-deep .el-button {
|
||||
width: 90px !important;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
::v-deep .operation-buttons .el-button {
|
||||
padding: 4px 8px;
|
||||
margin: 0 2px;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.selectClass {
|
||||
background-color: #4096ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.scoreText {
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.block {
|
||||
width: 4px;
|
||||
height: 24px;
|
||||
background-color: #4096ff;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.stepBox {
|
||||
position: absolute;
|
||||
top: 29px;
|
||||
height: 14px;
|
||||
width: 2px;
|
||||
background-color: #fff;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.totalBox {
|
||||
width: 150px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
}
|
||||
</style>
|
|
@ -1,44 +1,18 @@
|
|||
<template>
|
||||
<div class="project-list">
|
||||
<div class="search-bar">
|
||||
<el-form
|
||||
:inline="true"
|
||||
:model="searchForm"
|
||||
class="demo-form-inline"
|
||||
size="small"
|
||||
>
|
||||
<el-form :inline="true" :model="searchForm" class="demo-form-inline" size="small">
|
||||
<el-form-item label="任务名称" class="form-item">
|
||||
<el-input
|
||||
v-model="searchForm.taskName"
|
||||
placeholder="任务名称"
|
||||
style="width: 300px;"
|
||||
></el-input>
|
||||
<el-input v-model="searchForm.taskName" placeholder="任务名称" style="width: 300px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="任务状态" class="form-item">
|
||||
<el-select
|
||||
v-model="searchForm.taskStatus"
|
||||
placeholder="状态"
|
||||
clearable
|
||||
style="width: 300px;"
|
||||
|
||||
>
|
||||
<el-option
|
||||
v-for="item in statusList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
<el-select v-model="searchForm.taskStatus" placeholder="状态" clearable style="width: 300px">
|
||||
<el-option v-for="item in statusList" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="任务年份" class="form-item">
|
||||
<el-date-picker
|
||||
v-model="searchForm.year"
|
||||
type="year"
|
||||
style="width: 300px"
|
||||
placeholder="选择年份"
|
||||
value-format="yyyy"
|
||||
|
||||
>
|
||||
<el-date-picker v-model="searchForm.year" type="year" style="width: 300px" placeholder="选择年份"
|
||||
value-format="yyyy">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item class="search-buttons">
|
||||
|
@ -48,115 +22,65 @@
|
|||
</el-form>
|
||||
</div>
|
||||
<div class="table-actions mb10">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click="addTask"
|
||||
style="height: 36px"
|
||||
>+ 新增任务</el-button
|
||||
>
|
||||
<el-button type="primary" size="mini" @click="addTask" style="height: 36px">+ 新增任务</el-button>
|
||||
</div>
|
||||
<div class="f1 df">
|
||||
<CustomTable
|
||||
:columns="columns"
|
||||
:tableData="tableData"
|
||||
:total="total"
|
||||
:show-selection="false"
|
||||
:show-index="true"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
tableHeight="495px"
|
||||
>
|
||||
<CustomTable :columns="columns" :tableData="tableData" :total="total" :show-selection="false" :show-index="true"
|
||||
@size-change="handleSizeChange" @current-change="handleCurrentChange" tableHeight="495px">
|
||||
<template slot="operation" slot-scope="{ row }">
|
||||
<div class="operation-buttons">
|
||||
<el-button @click="editTask(row)" type="text" size="mini"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="row.taskStatus == 0"
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="setTask(row)"
|
||||
>指标配置</el-button
|
||||
>
|
||||
<el-button type="text" size="mini" @click="delTask(row)"
|
||||
>删除</el-button
|
||||
>
|
||||
<el-button @click="editTask(row)" type="text" size="mini">编辑</el-button>
|
||||
<el-button v-if="row.taskStatus == 0" type="text" size="mini" @click="setTask(row)">指标配置</el-button>
|
||||
<el-button type="text" size="mini" @click="delTask(row)">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</CustomTable>
|
||||
</div>
|
||||
<SelectUser
|
||||
:dialogVisible="userSelectDialogVisible"
|
||||
:currentSelectedUser="currentSelectedUser"
|
||||
:currentSelectedUserName="currentSelectedUserName"
|
||||
:showSelection="true"
|
||||
:highligt="false"
|
||||
:selectable="selectable"
|
||||
ref="selectUserRef"
|
||||
@confirm="handleUserConfirm"
|
||||
@close="handleUserClose"
|
||||
/>
|
||||
<el-dialog
|
||||
:title="isEdit ? '编辑考核任务' : '新增考核任务'"
|
||||
:visible.sync="dialogVisible1"
|
||||
width="25%"
|
||||
>
|
||||
<SelectUser :dialogVisible="userSelectDialogVisible" :currentSelectedUser="currentSelectedUser"
|
||||
:currentSelectedUserName="currentSelectedUserName" :showSelection="true" :highligt="false"
|
||||
:selectable="selectable" ref="selectUserRef" @confirm="handleUserConfirm" @close="handleUserClose" />
|
||||
<el-dialog :title="isEdit ? '编辑考核任务' : '新增考核任务'" :visible.sync="dialogVisible1" width="25%">
|
||||
<div>
|
||||
<el-form
|
||||
:model="taskData"
|
||||
size="small"
|
||||
ref="taskFormRef"
|
||||
:rules="rules"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form :model="taskData" size="small" ref="taskFormRef" :rules="rules" label-width="100px">
|
||||
<el-form-item label="任务名称" class="form-item" prop="taskName">
|
||||
<el-input
|
||||
v-model="taskData.taskName"
|
||||
placeholder="0/20"
|
||||
style="width: 90%"
|
||||
></el-input>
|
||||
<el-input v-model="taskData.taskName" placeholder="0/20" style="width: 90%"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="考核人员"
|
||||
class="form-item"
|
||||
prop="peopleNumberDetail"
|
||||
>
|
||||
<el-input
|
||||
v-model="taskData.peopleNumberDetail"
|
||||
placeholder="考核人员"
|
||||
readonly
|
||||
style="width: 90%"
|
||||
@click.native="openUserSelectDialog"
|
||||
><el-button slot="append" icon="el-icon-s-custom"></el-button
|
||||
></el-input>
|
||||
<el-form-item label="考核人员" class="form-item" prop="peopleNumberDetail">
|
||||
<el-input v-model="taskData.peopleNumberDetail" placeholder="考核人员" readonly style="width: 90%"
|
||||
@click.native="openUserSelectDialog"><el-button slot="append"
|
||||
icon="el-icon-s-custom"></el-button></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="截止时间" class="form-item" prop="endTime">
|
||||
<el-date-picker
|
||||
v-model="taskData.endTime"
|
||||
type="date"
|
||||
style="width: 90%"
|
||||
placeholder="选择日期"
|
||||
value-format="yyyy-MM-dd 23:59:59"
|
||||
:picker-options="{
|
||||
<el-date-picker v-model="taskData.endTime" type="date" style="width: 90%" placeholder="选择日期"
|
||||
value-format="yyyy-MM-dd 23:59:59" :picker-options="{
|
||||
disabledDate: disabledDate,
|
||||
}"
|
||||
>
|
||||
}">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="年份" class="form-item" prop="year">
|
||||
<el-date-picker
|
||||
v-model="taskData.year"
|
||||
type="year"
|
||||
style="width: 90%"
|
||||
placeholder="选择年份"
|
||||
value-format="yyyy"
|
||||
:picker-options="{
|
||||
<el-date-picker v-model="taskData.year" type="year" style="width: 90%" placeholder="选择年份"
|
||||
value-format="yyyy" :picker-options="{
|
||||
disabledDate: disabledDate,
|
||||
}"
|
||||
>
|
||||
}">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="考核模板" class="form-item" prop="templateId">
|
||||
<div>
|
||||
<el-radio-group v-model="taskData.templateType" @change="() => {
|
||||
taskData.templateId = ''
|
||||
}" :disabled="taskData.taskStatus == 2">
|
||||
<el-radio label="0">年度看板</el-radio>
|
||||
<el-radio label="1">季度看板</el-radio>
|
||||
<el-radio label="2">月度看板</el-radio>
|
||||
</el-radio-group>
|
||||
<el-select v-model="taskData.templateId" placeholder="选择看板" clearable style="width: 300px"
|
||||
:disabled="taskData.taskStatus == 2">
|
||||
<el-option v-for="item in modelList.filter((ele) => ele.templateType == taskData.templateType)"
|
||||
:key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
|
@ -168,16 +92,8 @@
|
|||
<div class="modal">
|
||||
<div class="left">
|
||||
<div class="setText" style="font-weight: 600">累计权重</div>
|
||||
<el-collapse
|
||||
v-model="letfValue"
|
||||
:accordion="true"
|
||||
style="height: 300px; overflow: auto"
|
||||
>
|
||||
<el-collapse-item
|
||||
v-for="(item, index) in scoreList"
|
||||
:key="index"
|
||||
:name="item.title"
|
||||
>
|
||||
<el-collapse v-model="letfValue" :accordion="true" style="height: 300px; overflow: auto">
|
||||
<el-collapse-item v-for="(item, index) in scoreList" :key="index" :name="item.title">
|
||||
<template #title>
|
||||
<div class="jcsb flex-row contentTitle">
|
||||
<span class="setTitle">{{ item.title }}</span>
|
||||
|
@ -185,25 +101,16 @@
|
|||
</div>
|
||||
</template>
|
||||
<div>
|
||||
<div
|
||||
v-for="(ele, index) in item.list"
|
||||
:key="index"
|
||||
class="flex-row jcsb leftSub"
|
||||
:class="{
|
||||
selectClass: selectLeftRow == ele.title + ele.type,
|
||||
}"
|
||||
@click="selectLeft(ele)"
|
||||
>
|
||||
<div v-for="(ele, index) in item.list" :key="index" class="flex-row jcsb leftSub" :class="{
|
||||
selectClass: selectLeftRow == ele.title + ele.type,
|
||||
}" @click="selectLeft(ele)">
|
||||
<div>{{ ele.title }}</div>
|
||||
<div class="statusText">{{ ele.weight }}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
<div
|
||||
class="flex-row jcsb"
|
||||
style="margin-top: 20px; padding-right: 15px"
|
||||
>
|
||||
<div class="flex-row jcsb" style="margin-top: 20px; padding-right: 15px">
|
||||
<div class="setTitle" style="font-weight: 600">总计</div>
|
||||
<div class="statusText">
|
||||
{{
|
||||
|
@ -214,64 +121,48 @@
|
|||
</div>
|
||||
<div class="right">
|
||||
<div class="flex-row jcsb" style="margin-bottom: 10px">
|
||||
<div style="width: 50%;font-weight: 600">指标</div>
|
||||
<div class="center" style="width: 50%;font-weight: 600">权重占比</div>
|
||||
<div style="width: 50%; font-weight: 600">指标</div>
|
||||
<div class="center" style="width: 50%; font-weight: 600">
|
||||
权重占比
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
v-for="(item, index) in (
|
||||
(
|
||||
(scoreList.find((ele) => ele.title == letfValue) || {})
|
||||
.list || []
|
||||
).find((ele) => ele.title + ele.type == selectLeftRow) || {}
|
||||
).rightArr || []"
|
||||
:key="index"
|
||||
style="margin-bottom: 10px"
|
||||
class="flex-row jcsb aic"
|
||||
>
|
||||
<div v-for="(item, index) in (
|
||||
(
|
||||
(scoreList.find((ele) => ele.title == letfValue) || {})
|
||||
.list || []
|
||||
).find((ele) => ele.title + ele.type == selectLeftRow) || {}
|
||||
).rightArr || []" :key="index" style="margin-bottom: 10px" class="flex-row jcsb aic">
|
||||
<div style="width: 50%; font-weight: 600">
|
||||
{{ item.reviewItem }}
|
||||
</div>
|
||||
<div class="center" style="width: 50%">
|
||||
<div
|
||||
class="flex-row jcsb"
|
||||
style="
|
||||
<div class="flex-row jcsb" style="
|
||||
margin-left: 10px;
|
||||
width: 100%;
|
||||
color: #999;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
"
|
||||
>
|
||||
">
|
||||
<div>0</div>
|
||||
<div v-show="item.weight != 20">20</div>
|
||||
</div>
|
||||
<div
|
||||
class="scoreText aic"
|
||||
v-show="item.weight != 0"
|
||||
:style="{
|
||||
left: item.weight * 4.5 - 2.5 + '%',
|
||||
}"
|
||||
>
|
||||
<img
|
||||
src="@/assets/task/score.png"
|
||||
:style="{
|
||||
height: '28px',
|
||||
width: '34px',
|
||||
zIndex: 0,
|
||||
position: 'absolute',
|
||||
top: '-2px',
|
||||
}"
|
||||
alt=""
|
||||
/>
|
||||
<div
|
||||
:style="{
|
||||
zIndex: 10,
|
||||
textIndent: item.weight < 10 ? '13px' : '10px',
|
||||
fontSize: '12px',
|
||||
}"
|
||||
>
|
||||
<div class="scoreText aic" v-show="item.weight != 0" :style="{
|
||||
left: item.weight * 4.5 - 2.5 + '%',
|
||||
}">
|
||||
<img src="@/assets/task/score.png" :style="{
|
||||
height: '28px',
|
||||
width: '34px',
|
||||
zIndex: 0,
|
||||
position: 'absolute',
|
||||
top: '-2px',
|
||||
}" alt="" />
|
||||
<div :style="{
|
||||
zIndex: 10,
|
||||
textIndent: item.weight < 10 ? '13px' : '10px',
|
||||
fontSize: '12px',
|
||||
}">
|
||||
{{ item.weight }}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -280,19 +171,10 @@
|
|||
<div class="scoreText">{{ item.weight }}%</div>
|
||||
<div>20%</div>
|
||||
</div> -->
|
||||
<div
|
||||
v-for="item in item.weight == 0 ? 0 : item.weight - 1"
|
||||
:key="item"
|
||||
class="stepBox"
|
||||
:style="{
|
||||
left: item * 5 + 4 + '%',
|
||||
}"
|
||||
></div>
|
||||
<el-slider
|
||||
v-model="item.weight"
|
||||
:max="20"
|
||||
@change="changeTotal"
|
||||
></el-slider>
|
||||
<div v-for="item in item.weight == 0 ? 0 : item.weight - 1" :key="item" class="stepBox" :style="{
|
||||
left: item * 5 + 4 + '%',
|
||||
}"></div>
|
||||
<el-slider v-model="item.weight" :max="20" @change="changeTotal"></el-slider>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -335,9 +217,8 @@ export default {
|
|||
if (value == 2) var color = "#999";
|
||||
else var color = "#4096FF";
|
||||
|
||||
return `<span style="color: ${color}">${
|
||||
value ? "已过期" : "进行中"
|
||||
}</span>`;
|
||||
return `<span style="color: ${color}">${value ? "已过期" : "进行中"
|
||||
}</span>`;
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -389,11 +270,14 @@ export default {
|
|||
userIdList: [],
|
||||
endTime: "",
|
||||
peopleNumber: 0,
|
||||
templateType:'0',
|
||||
templateId:'',
|
||||
year: "",
|
||||
taskStatus: 0
|
||||
},
|
||||
rules: {
|
||||
taskName: [
|
||||
{ required: true, message: "请输入活动名称", trigger: "blur" },
|
||||
{ required: true, message: "请输入任务名称", trigger: "blur" },
|
||||
{ min: 1, max: 20, message: "长度限制20个字符", trigger: "blur" },
|
||||
],
|
||||
peopleNumberDetail: [
|
||||
|
@ -403,11 +287,13 @@ export default {
|
|||
{ required: true, message: "请选择截止时间", trigger: "blur" },
|
||||
],
|
||||
year: [{ required: true, message: "请选择年份", trigger: "blur" }],
|
||||
templateId: [{ required: true, message: "请选择任务看板", trigger: "blur" }],
|
||||
},
|
||||
dialogVisible2: false,
|
||||
letfValue: "",
|
||||
scoreList: [],
|
||||
selectRow: {},
|
||||
modelList: [],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
|
@ -495,6 +381,10 @@ export default {
|
|||
userIdList: [],
|
||||
endTime: "",
|
||||
peopleNumber: 0,
|
||||
templateType: '0',
|
||||
templateId: '',
|
||||
taskStatus: 0
|
||||
|
||||
};
|
||||
this.selectRow = {};
|
||||
},
|
||||
|
@ -507,6 +397,9 @@ export default {
|
|||
this.taskData.peopleNumberDetail = row.peopleNumberDetail;
|
||||
this.taskData.userIdList = row.userIdList;
|
||||
this.taskData.endTime = row.endTime;
|
||||
this.taskData.templateId = row.templateId;
|
||||
this.taskData.templateType = row.templateType;
|
||||
this.taskData.taskStatus = row.taskStatus;
|
||||
this.taskData.year = String(row.year);
|
||||
this.selectRow = row;
|
||||
},
|
||||
|
@ -566,7 +459,7 @@ export default {
|
|||
},
|
||||
{
|
||||
title: "系统核算绩效指标",
|
||||
list: Object.keys(arrList["2"]).map((ele) => ({
|
||||
list: Object.keys(arrList["2"] || {}).map((ele) => ({
|
||||
title: ele,
|
||||
weight: arrList["2"][ele].reduce(
|
||||
(total, item) => (item.weight || 0) + total,
|
||||
|
@ -575,7 +468,7 @@ export default {
|
|||
rightArr: arrList["2"][ele],
|
||||
type: 2,
|
||||
})),
|
||||
weight: Object.values(arrList["2"]).reduce(
|
||||
weight: Object.values(arrList["2"] || {}).reduce(
|
||||
(total, item) =>
|
||||
(item.reduce((total, item) => (item.weight || 0) + total, 0) ||
|
||||
0) + total,
|
||||
|
@ -583,6 +476,9 @@ export default {
|
|||
),
|
||||
},
|
||||
];
|
||||
if (!arrList["2"]) {
|
||||
this.scoreList.length = 2
|
||||
}
|
||||
|
||||
this.dialogVisible2 = true;
|
||||
});
|
||||
|
@ -683,16 +579,25 @@ export default {
|
|||
});
|
||||
});
|
||||
},
|
||||
selectable(row,index){
|
||||
if(row.roles.find((ele)=>ele.roleName=='普通员工')){
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
selectable(row, index) {
|
||||
if (row.roles.find((ele) => ele.roleName == "普通员工")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
async getTaskModel() {
|
||||
const res = await taskApi.getTaskModel({ pageNum: 1, pageSize: 1000 });
|
||||
this.modelList = res.rows.map((ele) => ({
|
||||
value: ele.id,
|
||||
label: ele.templateName,
|
||||
templateType: ele.templateType
|
||||
}));
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getTaskList();
|
||||
this.getTaskModel();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -724,7 +629,8 @@ export default {
|
|||
}
|
||||
|
||||
.demo-form-inline .el-form-item:last-child {
|
||||
margin-right: 0; /* 移除最后一个元素的右边距 */
|
||||
margin-right: 0;
|
||||
/* 移除最后一个元素的右边距 */
|
||||
}
|
||||
|
||||
.form-item {
|
||||
|
@ -789,6 +695,7 @@ export default {
|
|||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
::v-deep .el-table th {
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -796,14 +703,17 @@ export default {
|
|||
::v-deep .el-table .cell {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
::v-deep .el-dialog {
|
||||
margin-top: 10% !important;
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: flex;
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 40%;
|
||||
padding: 20px;
|
||||
|
@ -811,89 +721,108 @@ export default {
|
|||
height: 450px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 60%;
|
||||
padding: 20px 40px;
|
||||
height: 450px;
|
||||
overflow: auto;
|
||||
|
||||
div.center {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.scoreBox {
|
||||
position: absolute;
|
||||
top: 45px;
|
||||
right: -20px;
|
||||
}
|
||||
|
||||
::v-deep .el-slider__runway {
|
||||
height: 14px;
|
||||
border-radius: 10px;
|
||||
margin: 10px !important;
|
||||
/* width: 95%; */
|
||||
}
|
||||
|
||||
::v-deep .el-slider__runway.disabled .el-slider__bar {
|
||||
height: 14px;
|
||||
border-radius: 10px;
|
||||
|
||||
background-color: #ff5722;
|
||||
}
|
||||
|
||||
::v-deep .el-slider__stop {
|
||||
height: 14px;
|
||||
border-radius: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
::v-deep .el-slider__bar {
|
||||
height: 14px;
|
||||
border-radius: 10px;
|
||||
background: linear-gradient(to right, #ffb144, #ff7d00);
|
||||
}
|
||||
|
||||
::v-deep .el-slider__button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.scoreText {
|
||||
color: #1686d8;
|
||||
}
|
||||
|
||||
.setText {
|
||||
margin-bottom: 20px;
|
||||
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.leftSub {
|
||||
padding: 10px 20px 10px 10px;
|
||||
margin-bottom: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.setTitle {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
::v-deep .el-collapse-item__content {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
::v-deep .el-collapse-item__header {
|
||||
}
|
||||
.contentTitle {
|
||||
}
|
||||
|
||||
::v-deep .el-collapse-item__header {}
|
||||
|
||||
.contentTitle {}
|
||||
|
||||
.statusText {
|
||||
color: #ff5722;
|
||||
}
|
||||
|
||||
::v-deep .el-collapse {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.search-buttons ::v-deep .el-button {
|
||||
width: 90px !important;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
::v-deep .operation-buttons .el-button {
|
||||
padding: 4px 8px;
|
||||
margin: 0 2px;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.selectClass {
|
||||
background-color: #4096ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.scoreText {
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
|
@ -903,12 +832,14 @@ export default {
|
|||
flex-direction: row;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.block {
|
||||
width: 4px;
|
||||
height: 24px;
|
||||
background-color: #4096ff;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.stepBox {
|
||||
position: absolute;
|
||||
top: 29px;
|
||||
|
@ -917,6 +848,7 @@ export default {
|
|||
background-color: #fff;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.totalBox {
|
||||
width: 150px;
|
||||
display: flex;
|
||||
|
|
|
@ -162,11 +162,11 @@
|
|||
</el-table-column>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template #default="scope">
|
||||
<div v-show="!disableTable">
|
||||
<div>
|
||||
<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)" v-show="!disableTable">
|
||||
{{ scope.row.loggerId && !scope.row.edit ? "编辑" : "确认" }}
|
||||
</el-button>
|
||||
|
||||
|
@ -174,6 +174,7 @@
|
|||
type="text"
|
||||
@click="handleDelete(scope.row, scope.$index)"
|
||||
style="color: #666"
|
||||
v-show="!disableTable"
|
||||
>
|
||||
{{ scope.row.loggerId && !scope.row.edit ? "删除" : "取消" }}
|
||||
</el-button>
|
||||
|
@ -188,7 +189,7 @@
|
|||
:close-on-click-modal="false"
|
||||
>
|
||||
<div v-loading="fileLoading">
|
||||
<div>
|
||||
<div v-show="!disableTable">
|
||||
<el-upload
|
||||
class="upload-demo"
|
||||
ref="upload"
|
||||
|
@ -249,7 +250,7 @@
|
|||
<el-table-column label="操作" width="120">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<el-button type="text" @click="delFile(scope.row)">
|
||||
<el-button type="text" @click="delFile(scope.row)" v-show="!disableTable">
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
|
@ -304,6 +305,7 @@ export default {
|
|||
filePng,
|
||||
zipPng,
|
||||
imagePng,
|
||||
delFileArr:[]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -328,7 +330,7 @@ export default {
|
|||
ele.showContent = false;
|
||||
return ele;
|
||||
});
|
||||
if (this.tableData.length == 0) {
|
||||
if (this.tableData.length == 0&&!this.disableTable) {
|
||||
this.handleAdd();
|
||||
}
|
||||
});
|
||||
|
@ -406,6 +408,12 @@ export default {
|
|||
await workLogApi.addLog(param);
|
||||
this.$emit("changeCaleder");
|
||||
}
|
||||
if(this.delFileArr.length){
|
||||
systemApi.delFile({ids:this.delFileArr}).then((res) => {
|
||||
this.fileList = []
|
||||
this.delFileArr=[]
|
||||
});
|
||||
}
|
||||
this.$modal.msgSuccess("操作成功");
|
||||
row.edit = false;
|
||||
this.getLogList();
|
||||
|
@ -445,6 +453,8 @@ export default {
|
|||
fileUrl: res.url,
|
||||
});
|
||||
} else {
|
||||
this.fileLoading = false;
|
||||
|
||||
this.$message({
|
||||
type: "error",
|
||||
message: res.msg,
|
||||
|
@ -455,10 +465,27 @@ export default {
|
|||
this.dialogVisibleFile = false;
|
||||
this.fileList = [];
|
||||
},
|
||||
saveFile() {
|
||||
async saveFile() {
|
||||
this.dialogVisibleFile = false;
|
||||
|
||||
this.checkRow.fileList = this.fileList;
|
||||
if(this.checkRow.loggerId){
|
||||
await workLogApi.editLog(this.checkRow);
|
||||
if(this.delFileArr.length){
|
||||
systemApi.delFileBatch(this.delFileArr.join(',')).then((res) => {
|
||||
this.fileList = []
|
||||
this.delFileArr=[]
|
||||
this.getLogList();
|
||||
|
||||
});
|
||||
}else{
|
||||
this.getLogList();
|
||||
|
||||
}
|
||||
}
|
||||
this.$message({
|
||||
type: "success",
|
||||
message: "保存成功!",
|
||||
});
|
||||
},
|
||||
async getAllProject() {
|
||||
const response = await projectApi.listProject({
|
||||
|
@ -563,15 +590,14 @@ export default {
|
|||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
}).then(() => {
|
||||
systemApi.delFile(row.id).then((res) => {
|
||||
this.fileList = this.fileList.filter(
|
||||
(ele) => ele.fileNewName != row.fileNewName
|
||||
);
|
||||
this.$message({
|
||||
this.delFileArr.push(row.id)
|
||||
this.fileList = this.fileList.filter(
|
||||
(ele) => ele.fileNewName != row.fileNewName
|
||||
);
|
||||
this.$message({
|
||||
type:'success',
|
||||
message: "删除成功!"
|
||||
})
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.fileList = this.fileList.filter(
|
||||
|
|
Loading…
Reference in New Issue