完成编辑项目属性功能

main
wuyize 2022-07-12 17:42:48 +08:00
parent 48d95b0244
commit 291eb9f596
3 changed files with 529 additions and 36 deletions

View File

@ -0,0 +1,438 @@
<template>
<el-dialog title="编辑项目信息" v-model="dialogFormVisible" :width="'1050px'">
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="110px"
class="demo-ruleForm">
<!-- 第1行 -->
<el-row>
<el-col :span="24">
<el-form-item label="项目名称" prop="projectName">
<el-input disabled v-model="ruleForm.projectName"></el-input>
</el-form-item>
</el-col>
</el-row>
<!-- 第2行 -->
<el-row>
<el-col :span="6">
<el-form-item label="英文简称" prop="projectAbbreviation">
<el-input v-model="ruleForm.projectAbbreviation"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="项目主类" prop="projectClassId" >
<el-select disabled v-model="ruleForm.projectClassId" placeholder="请选择" @change="onProjectClassChange">
<el-option
v-for="item in projectClasses"
:label="item.projectClassName"
:value="item.projectClassId"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="项目子类" prop="projectSubclassId">
<el-select disabled v-model="ruleForm.projectSubclassId" placeholder="请选择">
<el-option
v-for="item in currentProjectSubClasses"
:label="item.projectClassName"
:value="item.projectClassId"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="重要程度" prop="projectImportance">
<el-select v-model="ruleForm.projectImportance" placeholder="请选择">
<el-option label="A" value="A"></el-option>
<el-option label="B" value="B"></el-option>
<el-option label="C" value="C"></el-option>
<el-option label="D" value="D"></el-option>
<el-option label="E" value="E"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- 第3行 -->
<el-row>
<el-col :span="6">
<el-form-item label="合同额" prop="contractAmount">
<el-input v-model="ruleForm.contractAmount"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="预期完成度" prop="expectedCompletion">
<el-input v-model="ruleForm.expectedCompletion">
<template #suffix>
<span>%</span>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="计划总人月" prop="projectManMonth">
<el-input v-model="ruleForm.projectManMonth"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="项目启动日期" required>
<el-form-item prop="projectStartDate">
<el-date-picker
type="date"
placeholder="选择日期"
v-model="ruleForm.projectStartDate"
style="width: 100%;"
></el-date-picker>
</el-form-item>
</el-form-item>
</el-col>
</el-row>
<!-- 第4行 -->
<el-row>
<el-col :span="6">
<el-form-item label="计划上线日期" required>
<el-form-item prop="projectOnlineDate">
<el-date-picker
type="date"
placeholder="选择日期"
v-model="ruleForm.projectOnlineDate"
style="width: 100%;"
></el-date-picker>
</el-form-item>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="计划初验日期" required>
<el-form-item prop="projectFirstTestDate">
<el-date-picker
type="date"
placeholder="选择日期"
v-model="ruleForm.projectFirstTestDate"
style="width: 100%;"
></el-date-picker>
</el-form-item>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="计划终验日期" required>
<el-form-item prop="projectFinalTestDate">
<el-date-picker
type="date"
placeholder="选择日期"
v-model="ruleForm.projectFinalTestDate"
style="width: 100%;"
></el-date-picker>
</el-form-item>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="计划结项日期" required>
<el-form-item prop="projectEndDate">
<el-date-picker
type="date"
placeholder="选择日期"
v-model="ruleForm.projectEndDate"
style="width: 100%;"
></el-date-picker>
</el-form-item>
</el-form-item>
</el-col>
</el-row>
<!-- 第5行 -->
<el-row>
<el-col :span="6">
<el-form-item label="财务编码" prop="financialCode">
<el-input v-model="ruleForm.financialCode"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="所属部门" prop="projectDepartment">
<el-input disabled v-model="ruleForm.projectDepartment"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="所属区域" prop="projectArea">
<el-input disabled v-model="ruleForm.projectArea"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="所属公司" prop="projectCompany">
<el-input disabled v-model="ruleForm.projectCompany"></el-input>
</el-form-item>
</el-col>
</el-row>
<!-- 第6行 -->
<el-row>
<el-col :span="24">
<el-form-item label="项目描述" prop="projectDescription">
<el-input type="textarea" v-model="ruleForm.projectDescription"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<!-- 按钮 -->
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="submitForm('ruleForm')"></el-button>
</span>
</template>
</el-dialog>
</template>
<script>
import {ElMessage} from "element-plus";
import request from "../utils/request";
export default {
name: "EditProjectDialog",
data() {
let validateAbbreviation = (rule, value, callback) => {//
var reg = new RegExp("^[A-Za-z0-9]+$");
if (!value) {//callback,
return callback()
} else {
if (!reg.test(value)) {
return callback(new Error("只能输入字母和数字"))
}
}
return callback()
}
let validateAmount = (rule, value, callback) => {//0,2
var reg = new RegExp("^(([0-9]|([1-9][0-9]{0,9}))((\\.[0-9]{1,2})?))$");
if (!value) {//callback,
return callback()
} else {
if (!reg.test(value)) {
return callback(new Error("请输入正确的合同额"))
}
}
return callback()
}
let validateFinancial = (rule, value, callback) => {//
var reg = new RegExp("^\\d+$|^\\d+[.]?\\d+$");
if (!value) {//callback,
return callback()
} else {
if (!reg.test(value)) {
return callback(new Error("请输入正确的财务编码"))
}
}
return callback()
}
return {
formLabelWidth: '120px',
currentProjectSubClasses: [],
ruleForm: {
projectName: '', //
projectAbbreviation: '',//
projectClassId: '',//
projectSubclassId: '',//
projectImportance: '',//
contractAmount: '',//
expectedCompletion: '',//
projectManMonth: '',//
projectStartDate: '',//
projectOnlineDate: '',//线
projectFirstTestDate: '',//
projectFinalTestDate: '',//
projectEndDate: '',//
financialCode: '',//
projectDepartment: '',//
projectArea: '',//
projectCompany: '',//
projectDescription: '',//
},
rules: {
projectName: [//
{required: true, message: '请输入项目名称', trigger: 'blur'}
],
projectAbbreviation: [//
{validator: validateAbbreviation}
//
],
projectClassId: [//
{required: true, message: '请选择项目主类', trigger: 'change'},
],
projectSubclassId: [//
{required: true, message: '请选择项目子类', trigger: 'change'},
],
projectImportance: [//
{required: true, message: '请选择重要程度', trigger: 'change'},
],
contractAmount: [//
{validator: validateAmount}//
//0
],
expectedCompletion: [//
{required: true, message: '请输入预期完成度', trigger: 'blur'},
{
validator: function (rule, value, callback) {
//0-100
if (!/(^[1-9]\d$)|(^\d$)|(^100$)/.test(value)) {
callback(new Error("请输入正确的完成度"));
} else {
//
callback();
}
}, trigger: 'blur'
},
],
projectManMonth: [//
{required: true, message: '请输入计划总人月', trigger: 'blur'},
{
validator: function (rule, value, callback) {
//>0
if (!/^[1-9]*[1-9][0-9]*$/.test(value)) {
callback(new Error("请输入正确的人月数"));
} else {
//
callback();
}
}, trigger: 'blur'
},
],
projectStartDate: [//
{type: 'date', required: true, message: '请选择计划总人月', trigger: 'change'},
],
projectOnlineDate: [//线
{type: 'date', required: true, message: '请选择计划上线日期', trigger: 'change'},
],
projectFirstTestDate: [//
{type: 'date', required: true, message: '请选择计划初验日期', trigger: 'change'},
],
projectFinalTestDate: [//
{type: 'date', required: true, message: '请选择计划终验日期', trigger: 'change'},
],
projectEndDate: [//
{type: 'date', required: true, message: '请选择计划结项日期', trigger: 'change'},
],
financialCode: [//
{validator: validateFinancial}
//
],
projectDepartment: [//
{required: true, message: '请输入所属部门', trigger: 'blur'},
],
projectArea: [//
{required: true, message: '请输入所属区域', trigger: 'blur'},
],
projectCompany: [//
{required: true, message: '请输入所属公司', trigger: 'blur'},
],
projectDescription: [//
//
],
},
}
},
props: {
dialogFormVisible: Boolean,
projectClasses: Array,
projectSubClasses: Array,
projectInfo: {
projectName: '', //
projectAbbreviation: '',//
projectClassId: '',//
projectSubclassId: '',//
projectImportance: '',//
contractAmount: '',//
expectedCompletion: '',//
projectManMonth: '',//
projectStartDate: '',//
projectOnlineDate: '',//线
projectFirstTestDate: '',//
projectFinalTestDate: '',//
projectEndDate: '',//
financialCode: '',//
projectDepartment: '',//
projectArea: '',//
projectCompany: '',//
projectDescription: '',//
},
},
emits: ['edited'],
watch: {
projectInfo: function (val) {
this.ruleForm = val //
this.currentProjectSubClasses = []
for (const record of this.projectSubClasses) {
if (record.classFatherId === val.projectClassId)
this.currentProjectSubClasses.push(record)
}
},
},
methods: {
onProjectClassChange(val) {
this.ruleForm.projectSubclassId = ''
this.currentProjectSubClasses = []
for (const record of this.projectSubClasses) {
if (record.classFatherId === val)
this.currentProjectSubClasses.push(record)
}
},
//
submitForm(formName) {
const that = this
//this.$emit("created");
//
this.$refs[formName].validate((valid) => {
if (valid) {
console.log('submit')
let { ...form} = this.ruleForm
form.projectFinalTestDate = form.projectFinalTestDate.getTime() / 1000
form.projectEndDate = form.projectEndDate.getTime() / 1000
form.projectFirstTestDate = form.projectFirstTestDate.getTime() / 1000
form.projectOnlineDate = form.projectOnlineDate.getTime() / 1000
form.projectStartDate = form.projectStartDate.getTime() / 1000
request({
url: `project/${this.$route.params.projectId}`,
method: 'put',
data: form
}).then(response => {
//console.log(response)
if (response.data.code === 200) {
//console.log(response.data.data.records)
//that.dialogFormVisible = false
that.$emit("edited");
ElMessage({
message: '修改成功',
type: 'success',
})
}
}).catch(function (error) {
console.log(error)
})
} else {
console.log('error submit!!')
return false
}
})
},
//
resetForm(formName) {
this.$refs[formName].resetFields()
},
},
}
</script>

View File

@ -1,7 +1,8 @@
<template>
<div style="width: 100%;height: 100%;display: flex;flex-direction: column;align-items: stretch">
<p style="margin-left: 40px;font-family: 'Segoe UI',sans-serif;font-size: 20px;font-weight: bold;color: #606266">已结项项目</p>
<p style="margin-left: 40px;font-family: 'Segoe UI',sans-serif;font-size: 20px;font-weight: bold;color: #606266">
已结项项目</p>
<div style="flex: 1; margin: 30px 30px 10px 30px; background-color: white; border-radius: 10px;padding: 20px;
display: flex;flex-direction: column;justify-content: space-between">
@ -11,27 +12,32 @@
class="projectTable"
:height="tableHeight"
@sort-change="onSortChange"
@row-click="onRowClick"
:data="tableData">
<el-table-column prop="projectName" label="项目名称" min-width="15%" sortable="custom"/>
<el-table-column prop="contractAmount" label="合同额" min-width="10%" :formatter="priceFormatter" sortable="custom"/>
<el-table-column prop="contractAmount" label="合同额" min-width="10%" :formatter="priceFormatter"
sortable="custom"/>
<el-table-column prop="projectImportance" label="重要程度" min-width="10%" sortable="custom"/>
<el-table-column prop="projectClassName" label="项目分类" min-width="10%"/>
<el-table-column prop="projectSubclassName" label="项目类型" min-width="10%"/>
<el-table-column label="项目进度" min-width="35%" >
<el-table-column label="项目进度" min-width="35%">
<template #default="scope">
<el-progress :text-inside="true" :stroke-width="18"
:status="(scope.row.totalNum!==0&&scope.row.completeNum===scope.row.totalNum) ? 'success' : ''"
:percentage="scope.row.totalNum===0?0:Math.round(scope.row.completeNum*100/scope.row.totalNum)"></el-progress>
<el-progress
:class="scope.row.completeNum===0 ? 'blackTextProgress' : ''"
:text-inside="true" :stroke-width="18"
:status="(scope.row.totalNum!==0&&scope.row.completeNum===scope.row.totalNum) ? 'success' : ''"
:percentage="scope.row.totalNum===0?0:Math.round(scope.row.completeNum*100/scope.row.totalNum)"/>
</template>
</el-table-column>
<el-table-column prop="projectClosedDate" label="结项日期" min-width="10%" align="right" :formatter="dateFormatter"/>
<el-table-column prop="projectClosedDate" label="结项日期" min-width="10%" align="right"
:formatter="dateFormatter"/>
</el-table>
<!-- 分页 -->
<el-pagination
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
v-model:currentPage ="currentPage"
v-model:currentPage="currentPage"
:page-sizes="[5, 10, 15, 20]"
v-model:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
@ -44,14 +50,14 @@
<script setup>
// table
import {getCurrentInstance, onMounted, ref, watch } from "vue";
import { useRouter } from 'vue-router'
import {getCurrentInstance, onMounted, ref, watch} from "vue";
import {useRouter} from 'vue-router'
import request from "../utils/request";
const tableRef = ref(null);
// table
const tableHeight = ref();
const { proxy, ctx } = getCurrentInstance()
const {proxy, ctx} = getCurrentInstance()
onMounted(() => {
// innerHeight-offsetTop-110
tableHeight.value = window.innerHeight - tableRef.value.$el.offsetTop - 110;
@ -91,7 +97,7 @@ const getClosedProjects = () => {
console.log(error)
})
}
const onSortChange = ( val) => {
const onSortChange = (val) => {
console.log(val)
const that = this;
request({
@ -100,8 +106,8 @@ const onSortChange = ( val) => {
params: {
pageCurrent: currentPage.value,
pageSize: pageSize.value,
sortBy: val.order?val.prop:'projectClosedDate',
asc: val.order==='ascending',
sortBy: val.order ? val.prop : 'projectClosedDate',
asc: val.order === 'ascending',
paramMap: {
completed: true
}
@ -149,29 +155,34 @@ import router from "../router";
export default {
name: "ClosedProject",
data() {
return {
}
return {}
},
methods: {
onRowClick(row, column, event) {
router.push({path: '/project/' + row.projectId})
},
priceFormatter(row, column) {
return row[column.property]/10000 + '万';
return row[column.property] / 10000 + '万';
},
dateFormatter(row, column) {
const moment = require('moment');
const date = row[column.property];
if (date === undefined || date===null) {
if (date === undefined || date === null) {
return ''
}
return moment(date*1000).format("yyyy-MM-DD")
return moment(date * 1000).format("yyyy-MM-DD")
},
}
}
</script>
<style scoped>
.blackTextProgress >>> .el-progress-bar__innerText {
color: var(--el-table-text-color);
}
.projectTable {
width: 100%;
}

View File

@ -23,7 +23,7 @@
<p>{{ projectCreatorName }}</p>
</el-col>
</el-row>
<el-row >
<el-row>
<el-col :span="12">
<p class="p-subtitle">开始时间</p>
<p>{{ formatDate(project.projectCreatedTime) }}</p>
@ -38,7 +38,7 @@
<p class="p-subtitle">进度</p>
<el-progress
:status="(totalNum!==0&&completeNum===totalNum) ? 'success' : ''"
:percentage="totalNum===0?0:Math.round(completeNum*100/totalNum)" />
:percentage="totalNum===0?0:Math.round(completeNum*100/totalNum)"/>
</el-col>
</el-row>
@ -53,13 +53,17 @@
</div>
</div>
</div>
<div style="height: 400px;margin: 0 30px 30px 30px;
display: flex;flex-direction: row;justify-content: space-between">
<div style="margin: 0 30px 30px 30px;
display: flex;flex-direction: row;justify-content: space-between;align-items: stretch">
<div style="width: 60%; height: 100%;display: flex;flex-direction: column">
<p class="p-title" style="margin-left: 10px">详细信息</p>
<div style="margin: 0 10px 0 10px;
display: flex;flex-direction: row;justify-content: space-between">
<p style="font-family: 'Segoe UI',sans-serif;font-size: 20px;font-weight: bold;color: #606266">详细信息</p>
<el-button v-if="projectAccessLevel===1" type="primary" @click.native="onEditProjectClick"></el-button>
</div>
<div style="flex:1;margin-top: 30px;padding: 20px;
display: flex;flex-direction: column; justify-content: space-between;background-color: white; border-radius: 10px; ">
<el-row>
<el-row class="row-info">
<el-col :span="6">
<p class="p-subtitle">英文简称</p>
<p>{{ project.projectAbbreviation }}</p>
@ -77,14 +81,14 @@
<p>{{ project.projectImportance }}</p>
</el-col>
</el-row>
<el-row >
<el-row class="row-info">
<el-col :span="6">
<p class="p-subtitle">合同额</p>
<p>{{ Math.round(project.contractAmount/10000)+'万' }}</p>
<p>{{ Math.round(project.contractAmount / 10000) + '万' }}</p>
</el-col>
<el-col :span="6">
<p class="p-subtitle">预计完成度</p>
<p>{{ project.expectedCompletion+'%' }}</p>
<p>{{ project.expectedCompletion + '%' }}</p>
</el-col>
<el-col :span="6">
<p class="p-subtitle">计划总人月</p>
@ -96,7 +100,7 @@
</el-col>
</el-row>
<el-row >
<el-row class="row-info">
<el-col :span="6">
<p class="p-subtitle">计划上线日期</p>
<p>{{ formatDate(project.projectOnlineDate) }}</p>
@ -114,7 +118,7 @@
<p>{{ formatDate(project.projectEndDate) }}</p>
</el-col>
</el-row>
<el-row >
<el-row class="row-info">
<el-col :span="6">
<p class="p-subtitle">财务编码</p>
<p>{{ project.financialCode }}</p>
@ -132,11 +136,18 @@
<p>{{ project.projectCompany }}</p>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<p class="p-subtitle">项目描述</p>
<p>{{ project.projectDescription }}</p>
</el-col>
</el-row>
</div>
</div>
<div style="flex: 1;margin-left: 30px;height: 100%;display: flex;flex-direction: column">
<p class="p-title" style="margin-left: 10px">项目描述</p>
<div style="flex: 1;margin-left: 30px;display: flex;flex-direction: column">
<p class="p-title" style="margin-left: 10px">公告</p>
<div style="flex:1;margin-top: 30px;padding: 20px;
display: flex;flex-direction: column; justify-content: space-between;background-color: white; border-radius: 10px;">
<p>{{ project.projectDescription }}</p>
@ -146,20 +157,27 @@
</el-scrollbar>
<EditProjectDialog
:dialogFormVisible="editProjectDialogVisible" :projectClasses="projectClasses"
:projectSubClasses="projectSubClasses"
:projectInfo="editProjectInfo"
@edited="onEdited"/>
</template>
<script setup>
import {ref} from 'vue'
</script>
<script>
import request from "@/utils/request";
import moment from "moment";
import EditProjectDialog from "../components/EditProjectDialog";
export default {
name: "ProjectInfo",
components: {},
components: {EditProjectDialog},
data() {
return {
project: {
@ -190,7 +208,10 @@ export default {
projectClasses: [],
projectSubClasses: [],
viewHeight: 0
viewHeight: 0,
editProjectDialogVisible: false,
editProjectInfo: {}
}
},
props: {
@ -221,13 +242,17 @@ export default {
return ' '
},
projectSubClassName() {
console.log(this.project.projectSubclassId)
if (this.project.projectSubclassId) {
const that = this
const projectSubClass = this.projectSubClasses.find(function (item, index, arr) {
return item.projectClassId === that.project.projectSubclassId;
})
if (projectSubClass)
if (projectSubClass) {
return projectSubClass.projectClassName
}
}
return ' '
},
@ -255,7 +280,22 @@ export default {
};
},
methods: {
onEditProjectClick() {
let {...copy} = this.project
copy.projectStartDate = new Date(this.project.projectStartDate*1000)
copy.projectOnlineDate = new Date(this.project.projectOnlineDate*1000)
copy.projectFirstTestDate = new Date(this.project.projectFirstTestDate*1000)
copy.projectFinalTestDate = new Date(this.project.projectFinalTestDate*1000)
copy.projectEndDate = new Date(this.project.projectEndDate*1000)
this.editProjectInfo = copy
//this.getProjectClass()
this.editProjectDialogVisible = true
},
onEdited() {
this.editProjectDialogVisible = false
this.getProjectInfo()
},
formatDate(date) {
if (date)
return moment(date * 1000).format("yyyy年MM月DD日")
@ -316,6 +356,10 @@ export default {
</script>
<style scoped lang="scss">
.row-info {
margin-bottom: 40px;
}
p.p-subtitle {
font-size: 14px;
margin-bottom: 10px;