feat(project): 项目管理功能增强
- 实现行业类型多选功能,支持多个行业筛选 - 添加技术方案终审下载按钮,仅在联合试用为1时显示 - 集成文件上传组件,支持项目相关附件管理 - 新增授权、终端、服务器等技术信息字段管理 - 实现技术方案单个导出功能,添加权限控制 - 优化项目详情展示,增加虚拟机配置信息 - 添加会审结论和项目风险技术问题字段 - 完善项目表单验证和数据绑定逻辑 - 修复联合试用状态变更时的业务逻辑验证dev_1.0.0
parent
97bcc1ac0a
commit
59b045d457
|
|
@ -4,8 +4,10 @@ import request from '@/utils/request'
|
|||
export function listProject(query) {
|
||||
return request({
|
||||
url: '/sip/project/vue/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
method: 'post',
|
||||
data: query,
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -70,4 +72,11 @@ export function editJoinTrial(data) {
|
|||
needLoading:true
|
||||
})
|
||||
}
|
||||
export function exportSingle(id) {
|
||||
return request({
|
||||
url: `/sip/project/vue/joinTrial/export/${id}`,
|
||||
method: 'get',
|
||||
needLoading:true
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -185,15 +185,53 @@
|
|||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="关键技术问题" prop="keyProblem">
|
||||
<el-input v-model="form.keyProblem" type="textarea" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目简述" prop="projectDesc">
|
||||
<el-input v-model="form.projectDesc" type="textarea" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="服务器配置" prop="serverConfiguration">
|
||||
<el-form-item label="授权" prop="softwareInfo">
|
||||
<el-input v-model="form.softwareInfo" readonly type="textarea" />
|
||||
</el-form-item>
|
||||
<el-form-item label="终端" prop="hardwareInfo">
|
||||
<el-input v-model="form.hardwareInfo" readonly type="textarea" />
|
||||
</el-form-item>
|
||||
<el-form-item label="其他终端、外设" prop="terminalPeripheral">
|
||||
<el-input v-model="form.terminalPeripheral" type="textarea" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="服务器" prop="serverConfiguration">
|
||||
<el-input v-model="form.serverConfiguration" type="textarea" readonly />
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="管理端版本" prop="managementVersion">
|
||||
<el-input v-model="form.managementVersion" readonly></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="桌面虚拟机OS版本" prop="desktopVmOsVersion">
|
||||
<el-input v-model="form.desktopVmOsVersion" readonly></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="虚拟机规格、数量" prop="vmSpecQuantity">
|
||||
<el-input v-model="form.vmSpecQuantity" readonly></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="项目风险及技术问题" prop="keyProblem">
|
||||
<el-input v-model="form.keyProblem" type="textarea" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="会审结论" prop="jointTrialResult">
|
||||
<el-input v-model="form.jointTrialResult" type="textarea" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="附件">
|
||||
<file-upload
|
||||
:value="fileList"
|
||||
:limit="5"
|
||||
:file-size="10"
|
||||
:file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'pdf', 'zip', 'rar']"
|
||||
:disabled="true"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="配置信息" name="productConfig">
|
||||
|
|
@ -330,10 +368,11 @@
|
|||
<script>
|
||||
import { getProject } from "@/api/project/info";
|
||||
import ProductConfig from "./ProductConfig.vue";
|
||||
import FileUpload from "@/components/FileUpload";
|
||||
|
||||
export default {
|
||||
name: "ProjectDetailDrawer",
|
||||
components: { ProductConfig },
|
||||
components: { ProductConfig, FileUpload },
|
||||
dicts: ['bg_type', 'bg_yys', 'bg_hysy', 'project_stage', 'operate_institution'],
|
||||
props: {
|
||||
visible: {
|
||||
|
|
@ -347,13 +386,15 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
fileList: [],
|
||||
form: {
|
||||
productConfig: {},
|
||||
projectWorkProgressList: [],
|
||||
projectOperateLogList: [],
|
||||
projectPocInfo: {
|
||||
projectPocInfoDetailList: []
|
||||
}
|
||||
},
|
||||
projectFileList: []
|
||||
},
|
||||
activeTab: 'projectInfo',
|
||||
localVisible: this.visible,
|
||||
|
|
@ -388,8 +429,10 @@ export default {
|
|||
projectData.projectOperateLogList = projectData.projectOperateLogList || [];
|
||||
projectData.projectPocInfo = projectData.projectPocInfo || { projectPocInfoDetailList: [] };
|
||||
projectData.projectPocInfo.projectPocInfoDetailList = projectData.projectPocInfo.projectPocInfoDetailList || [];
|
||||
projectData.projectFileList = projectData.projectFileList || [];
|
||||
|
||||
this.form = projectData;
|
||||
this.fileList = this.form.projectFileList;
|
||||
this.setupIndustryOptions();
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -201,15 +201,87 @@
|
|||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="关键技术问题" prop="keyProblem">
|
||||
<el-input v-model="form.keyProblem" type="textarea" placeholder="请输入关键技术问题" maxlength="500" :disabled="isFormDisabled" />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目简述" prop="projectDesc">
|
||||
<el-input v-model="form.projectDesc" type="textarea" placeholder="请输入项目简述" maxlength="500" :disabled="isFormDisabled" />
|
||||
</el-form-item>
|
||||
<el-form-item label="服务器配置" prop="serverConfiguration">
|
||||
<el-form-item label="授权" prop="softwareInfo">
|
||||
<el-input v-model="form.softwareInfo" readonly type="textarea" placeholder="其他终端、外设" maxlength="500" :disabled="isFormDisabled" />
|
||||
</el-form-item>
|
||||
<el-form-item label="终端" prop="hardwareInfo">
|
||||
<el-input v-model="form.hardwareInfo" readonly type="textarea" placeholder="其他终端、外设" maxlength="500" :disabled="isFormDisabled" />
|
||||
</el-form-item>
|
||||
<el-form-item label="其他终端、外设" prop="terminalPeripheral">
|
||||
<el-input v-model="form.terminalPeripheral" type="textarea" placeholder="其他终端、外设" maxlength="500" :disabled="isFormDisabled" />
|
||||
</el-form-item>
|
||||
<el-form-item label="服务器" prop="serverConfiguration">
|
||||
<el-input v-model="form.serverConfiguration" type="textarea" placeholder="请输入服务器配置" maxlength="500" :disabled="isFormDisabled" />
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="管理端版本" prop="managementVersion">
|
||||
<el-input v-model="form.managementVersion"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="桌面虚拟机OS版本" prop="desktopVmOsVersion">
|
||||
<el-input v-model="form.desktopVmOsVersion"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="虚拟机规格、数量" prop="vmSpecQuantity">
|
||||
<el-input v-model="form.vmSpecQuantity"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="项目风险及技术问题" prop="keyProblem">
|
||||
<template #label>
|
||||
项目风险及技术问题<el-tooltip class="item" effect="dark" placement="right-start">
|
||||
<template #content>
|
||||
<el-row>
|
||||
1.方案风险(如涉及对接外置存储、安全网关部署、城域网等复杂网络、两节点超融合部署、Spacecenter多异地部署、备份对接、功能开发需求评估等)
|
||||
</el-row>
|
||||
<el-row>
|
||||
2.技术风险(如涉及功能不满足项强行应标、POC测试不满足用例、老版本部署、混管升级、跨网段唤醒等技术要求)
|
||||
</el-row>
|
||||
<el-row>
|
||||
3.服务风险(如涉及异地部署、多区域部署、非省代/原厂交付、大规模点位部署等)
|
||||
</el-row>
|
||||
<el-row>
|
||||
4.其他风险(上述未列出的其他特殊风险)
|
||||
</el-row>
|
||||
</template>
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input v-model="form.keyProblem" type="textarea" placeholder="请输入关键技术问题" maxlength="500" :disabled="isFormDisabled" />
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item prop="jointTrialResult">
|
||||
<template #label>
|
||||
会审结论<el-tooltip class="item" effect="dark" placement="right-start">
|
||||
<template #content>
|
||||
<el-row>
|
||||
1.如果有POC测试项目,必须上传POC测试报告
|
||||
</el-row>
|
||||
<el-row>
|
||||
2.会审给出的结论,售前需与新华三销售或者客户确认认可,上传对话截图或者邮件截图
|
||||
</el-row>
|
||||
</template>
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input v-model="form.jointTrialResult" type="textarea" placeholder="请输入关键技术问题" maxlength="500" :disabled="isFormDisabled || !canUpdateJoinTrial" />
|
||||
</el-form-item>
|
||||
<el-form-item label="附件上传">
|
||||
<file-upload
|
||||
:value="fileList"
|
||||
@file-list-changed="handleFileListChanged"
|
||||
:limit="5"
|
||||
:file-size="10"
|
||||
:file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'pdf', 'zip', 'rar']"
|
||||
:disabled="isFormDisabled"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="配置信息" name="productConfig">
|
||||
|
|
@ -371,6 +443,8 @@ import SelectCustomer from "../../system/customer/selectCustomer.vue";
|
|||
import SelectPartner from "../../system/partner/selectPartner.vue";
|
||||
import SelectUser from "@/views/system/user/selectUser";
|
||||
import ProductConfig from "./ProductConfig.vue";
|
||||
import FileUpload from "@/components/FileUpload";
|
||||
import { getToken } from "@/utils/auth";
|
||||
import {isNaN} from "@riophae/vue-treeselect/src/utils";
|
||||
|
||||
export default {
|
||||
|
|
@ -381,9 +455,14 @@ export default {
|
|||
SelectPartner,
|
||||
SelectUser,
|
||||
ProductConfig,
|
||||
FileUpload,
|
||||
},
|
||||
dicts: ['bg_type', 'bg_yys', 'bg_hysy', 'project_stage', 'operate_institution'],
|
||||
props: {
|
||||
canUpdateJoinTrial:{
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
|
|
@ -413,6 +492,7 @@ export default {
|
|||
selectCustomerVisible: false,
|
||||
selectPartnerVisible: false,
|
||||
selectUserVisible: false,
|
||||
fileList: [],
|
||||
form: {
|
||||
competitorList: [],
|
||||
otherCompetitor: '',
|
||||
|
|
@ -425,7 +505,8 @@ export default {
|
|||
projectOperateLogList: [],
|
||||
projectPocInfo: {
|
||||
projectPocInfoDetailList: []
|
||||
}
|
||||
},
|
||||
projectFileList: []
|
||||
},
|
||||
rules: {
|
||||
projectName: [
|
||||
|
|
@ -504,6 +585,40 @@ export default {
|
|||
this.handleAdd();
|
||||
}
|
||||
}
|
||||
},
|
||||
'form.productConfig': {
|
||||
handler(newVal) {
|
||||
if (!newVal) return;
|
||||
|
||||
// 1. Authorization (software)
|
||||
const softwareList = newVal.softwareProjectProductInfoList || [];
|
||||
if (softwareList.length > 0) {
|
||||
this.form.softwareInfo = softwareList
|
||||
.filter(item => item.productBomCode || item.model || (item.quantity !== undefined && item.quantity !== null))
|
||||
.map(item => {
|
||||
const code = item.productBomCode || '';
|
||||
const model = item.model || '';
|
||||
const qty = (item.quantity !== undefined && item.quantity !== null && item.quantity !== '') ? item.quantity : '';
|
||||
return `${code},${model},${qty}个`;
|
||||
})
|
||||
.join(';');
|
||||
}
|
||||
|
||||
// 2. Terminal (hardware)
|
||||
const hardwareList = newVal.hardwareProjectProductInfoList || [];
|
||||
if (hardwareList.length > 0) {
|
||||
this.form.hardwareInfo = hardwareList
|
||||
.filter(item => item.productBomCode || item.model || (item.quantity !== undefined && item.quantity !== null))
|
||||
.map(item => {
|
||||
const code = item.productBomCode || '';
|
||||
const model = item.model || '';
|
||||
const qty = (item.quantity !== undefined && item.quantity !== null && item.quantity !== '') ? item.quantity : '';
|
||||
return `${code},${model},${qty}台`;
|
||||
})
|
||||
.join(';');
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -579,6 +694,7 @@ export default {
|
|||
projectPocInfo: {
|
||||
projectPocInfoDetailList: []
|
||||
},
|
||||
projectFileList: [],
|
||||
createAt: null,
|
||||
updatedAt: null
|
||||
};
|
||||
|
|
@ -586,6 +702,7 @@ export default {
|
|||
this.isFormDisabled = false;
|
||||
this.cityOptions = [];
|
||||
this.industryOptions = [];
|
||||
this.fileList = [];
|
||||
this.resetForm("form");
|
||||
},
|
||||
handleAdd() {
|
||||
|
|
@ -635,9 +752,17 @@ export default {
|
|||
this.$set(this.form, 'projectPocInfo', this.form.projectPocInfo || { projectPocInfoDetailList: [] });
|
||||
this.$set(this.form.projectPocInfo, 'projectPocInfoDetailList', this.form.projectPocInfo.projectPocInfoDetailList || []);
|
||||
|
||||
this.$set(this.form, 'projectFileList', this.form.projectFileList || []);
|
||||
this.fileList = this.form.projectFileList;
|
||||
|
||||
this.title = "修改项目管理";
|
||||
});
|
||||
},
|
||||
handleFileListChanged(fileList) {
|
||||
this.fileList = fileList;
|
||||
this.form.projectFileList = fileList;
|
||||
this.form.fileId = fileList.map(f => f.id).filter(id => !!id).join(',')
|
||||
},
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="行业" prop="industryType">
|
||||
<el-select v-model="queryParams.industryType" placeholder="请选择行业" clearable>
|
||||
<el-select multiple v-model="queryParams.industryTypeList" placeholder="请选择行业" clearable>
|
||||
<el-option
|
||||
v-for="item in searchIndustryOptions"
|
||||
:key="item.value"
|
||||
|
|
@ -237,6 +237,13 @@
|
|||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['sip:project:remove']"
|
||||
>删除</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@click="handleExportSingle(scope.row)"
|
||||
v-show="scope.row.jointTrial==='1'"
|
||||
>技术方案终审下载</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -256,6 +263,7 @@
|
|||
<project-form
|
||||
:visible.sync="projectFormVisible"
|
||||
:project-id="selectedProjectId"
|
||||
:canUpdateJoinTrial="canUpdateJoinTrial"
|
||||
@success="handleFormSuccess"
|
||||
/>
|
||||
|
||||
|
|
@ -265,7 +273,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import {listProject, delProject, exportProject, addCollect, updateProject, editJoinTrial} from "@/api/project/info";
|
||||
import {listProject, delProject, exportProject, addCollect, exportSingle, editJoinTrial} from "@/api/project/info";
|
||||
import ProjectDetailDrawer from "./ProjectDetailDrawer.vue";
|
||||
import ProjectForm from "./ProjectForm.vue";
|
||||
import OrderDetail from "../order/OrderDetail.vue";
|
||||
|
|
@ -317,6 +325,7 @@ export default {
|
|||
customerName: null,
|
||||
bgProperty: null,
|
||||
industryType: null,
|
||||
industryTypeList: null,
|
||||
agentName: null,
|
||||
jointTrial: null,
|
||||
collect: null,
|
||||
|
|
@ -336,13 +345,10 @@ export default {
|
|||
created() {
|
||||
this.getList();
|
||||
const permissions = store.getters && store.getters.permissions
|
||||
console.log(permissions)
|
||||
const all_permission = "*:*:*"
|
||||
debugger
|
||||
this.canUpdateJoinTrial = permissions.some(permission => {
|
||||
return all_permission === permission || "sip:project:jointTrial"===permission
|
||||
})
|
||||
console.log(this.canUpdateJoinTrial)
|
||||
},
|
||||
watch: {
|
||||
dateRange(val) {
|
||||
|
|
@ -415,6 +421,7 @@ export default {
|
|||
this.queryParams.lastWorkUpdateTimeStart = null;
|
||||
this.queryParams.lastWorkUpdateTimeEnd = null;
|
||||
this.queryParams.industryType = null; // Clear industry type
|
||||
this.queryParams.industryTypeList = null; // Clear industry type
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
|
|
@ -448,6 +455,10 @@ export default {
|
|||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
},
|
||||
handleExportSingle(row){
|
||||
window.location.href=process.env.VUE_APP_BASE_API +`/sip/project/vue/joinTrial/export/${row.id}`
|
||||
// exportSingle(row.id)
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.$modal.confirm('是否确认导出所有项目管理数据项?').then(() => {
|
||||
|
|
|
|||
|
|
@ -2,19 +2,30 @@ package com.ruoyi.sip.controller.vue;
|
|||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.config.RuoYiConfig;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.core.text.Convert;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.file.FileUtils;
|
||||
import com.ruoyi.sip.domain.OmsFileLog;
|
||||
import com.ruoyi.sip.domain.ProjectInfo;
|
||||
import com.ruoyi.sip.domain.ProjectOrderInfo;
|
||||
import com.ruoyi.sip.service.IOmsFileLogService;
|
||||
import com.ruoyi.sip.service.IProjectInfoService;
|
||||
import com.ruoyi.sip.service.IProjectOrderInfoService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
|
@ -27,6 +38,7 @@ import java.util.Map;
|
|||
* @date 2025-05-29
|
||||
*/
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequestMapping("/sip/project/vue")
|
||||
public class VueProjectInfoController extends BaseController {
|
||||
|
||||
|
|
@ -39,7 +51,7 @@ public class VueProjectInfoController extends BaseController {
|
|||
* 查询项目管理列表
|
||||
*/
|
||||
@RequiresPermissions("sip:project:list")
|
||||
@GetMapping("/list")
|
||||
@PostMapping("/list")
|
||||
public TableDataInfo list(ProjectInfo projectInfo) {
|
||||
startPage();
|
||||
projectInfo.setCurrentUserId(getUserId());
|
||||
|
|
@ -98,6 +110,49 @@ public class VueProjectInfoController extends BaseController {
|
|||
public AjaxResult editJoinTrial(@RequestBody ProjectInfo projectInfo) {
|
||||
return toAjax(projectInfoService.editJoinTrial(projectInfo));
|
||||
}
|
||||
@RequiresPermissions("sip:project:export")
|
||||
|
||||
@PostMapping("/export/joinTrial")
|
||||
public AjaxResult exportJoinTrial(ProjectInfo projectInfo) {
|
||||
return AjaxResult.success(projectInfoService.exportJoinTrial(projectInfo));
|
||||
}
|
||||
@GetMapping("/joinTrial/export/{id}")
|
||||
public void exportSingleJoinTrial(@PathVariable("id") Long id, @RequestParam(required = false) String fileName,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
try {
|
||||
if (id != null) {
|
||||
// 获取订单信息
|
||||
ProjectInfo projectInfo = projectInfoService.selectProjectInfoById(id);
|
||||
if (projectInfo == null) {
|
||||
throw new ServiceException("订单信息不存在");
|
||||
}
|
||||
if (!"1".equals(projectInfo.getJointTrial())){
|
||||
throw new ServiceException("项目未会审,无法导出");
|
||||
}
|
||||
// 新逻辑:生成填充了订单信息的合同模板
|
||||
byte[] fileBytes = projectInfoService.exportSingleJoinTrial(projectInfo);
|
||||
|
||||
// 设置响应头
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
|
||||
String downloadFileName = StringUtils.isEmpty(fileName) ? "技术会审_" + projectInfo.getProjectName() + ".docx" : fileName;
|
||||
FileUtils.setAttachmentResponseHeader(response, downloadFileName);
|
||||
|
||||
// 写入响应流
|
||||
response.getOutputStream().write(fileBytes);
|
||||
response.getOutputStream().flush();
|
||||
} else {
|
||||
// 原逻辑:直接下载模板文件
|
||||
String localPath = RuoYiConfig.getExcelTemplate();
|
||||
String downloadPath = localPath + File.separator + (StringUtils.isEmpty(fileName) ? "orderDownloadTemplate.docx" : fileName);
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
FileUtils.setAttachmentResponseHeader(response, StringUtils.isEmpty(fileName) ? "orderDownloadTemplate.docx" : fileName);
|
||||
FileUtils.writeBytes(downloadPath, response.getOutputStream());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("下载文件失败", e);
|
||||
throw new ServiceException("下载文件失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除项目管理
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import lombok.Data;
|
|||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -21,6 +22,7 @@ public class OmsFileLog extends BaseEntity {
|
|||
* 主键ID
|
||||
*/
|
||||
private Integer id;
|
||||
private List<Integer> idList;
|
||||
|
||||
/**
|
||||
* 新文件名
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ public class ProjectInfo extends BaseEntity
|
|||
/** 行业 */
|
||||
@Excel(name = "行业")
|
||||
private String industryType;
|
||||
private List<String> industryTypeList;
|
||||
|
||||
/** 代表处 */
|
||||
private String agentCode;
|
||||
|
|
@ -199,6 +200,38 @@ public class ProjectInfo extends BaseEntity
|
|||
private List<ProjectWorkProgress> projectWorkProgressList;
|
||||
private ProjectPocInfo projectPocInfo;
|
||||
|
||||
/** 授权信息 */
|
||||
@Excel(name = "授权信息")
|
||||
private String softwareInfo;
|
||||
|
||||
/** 终端类型 */
|
||||
@Excel(name = "终端类型")
|
||||
private String hardwareInfo;
|
||||
|
||||
/** 其它终端外设 */
|
||||
@Excel(name = "其它终端外设")
|
||||
private String terminalPeripheral;
|
||||
|
||||
/** 管理端版本 */
|
||||
@Excel(name = "管理端版本")
|
||||
private String managementVersion;
|
||||
|
||||
/** 桌面虚拟机OS版本 */
|
||||
@Excel(name = "桌面虚拟机OS版本")
|
||||
private String desktopVmOsVersion;
|
||||
|
||||
/** 虚拟机规格及数量 */
|
||||
@Excel(name = "虚拟机规格及数量")
|
||||
private String vmSpecQuantity;
|
||||
|
||||
/** 会审结论 */
|
||||
@Excel(name = "会审结论")
|
||||
private String jointTrialResult;
|
||||
|
||||
private List<OmsFileLog> projectFileList;
|
||||
private String fileId;
|
||||
|
||||
|
||||
private Boolean availableForOrder;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,4 +46,6 @@ public interface OmsFileLogMapper {
|
|||
*/
|
||||
int batchRemove(Integer[] ids);
|
||||
|
||||
int insertBatch(List<OmsFileLog> fileLogList);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,4 +70,8 @@ public interface IProjectInfoService
|
|||
ProjectInfo selectProjectInfoByOrderCode(String orderCode);
|
||||
|
||||
int editJoinTrial(ProjectInfo projectInfo);
|
||||
|
||||
byte[] exportSingleJoinTrial(ProjectInfo projectInfo);
|
||||
|
||||
String exportJoinTrial(ProjectInfo projectInfo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
package com.ruoyi.sip.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.ruoyi.sip.domain.OmsFileLog;
|
||||
import com.ruoyi.sip.mapper.OmsFileLogMapper;
|
||||
import com.ruoyi.sip.service.IOmsFileLogService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author ch
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package com.ruoyi.sip.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.NumberChineseFormatter;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.metadata.CellData;
|
||||
import com.alibaba.excel.metadata.Head;
|
||||
|
|
@ -10,6 +12,7 @@ import com.alibaba.excel.write.metadata.style.WriteCellStyle;
|
|||
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
|
||||
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
|
||||
import com.ruoyi.common.annotation.DataScope;
|
||||
import com.ruoyi.common.config.RuoYiConfig;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.text.Convert;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
|
|
@ -27,13 +30,20 @@ import com.ruoyi.sip.service.*;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.xwpf.usermodel.*;
|
||||
import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForOffsetTime;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.Period;
|
||||
import java.time.ZoneId;
|
||||
|
|
@ -67,6 +77,9 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
@Autowired
|
||||
private ICustomerInfoService customerInfoService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private IOmsFileLogService omsFileLogService;
|
||||
@Autowired
|
||||
private IProjectUserCollectInfoService projectUserCollectInfoService;
|
||||
@Autowired
|
||||
|
|
@ -75,7 +88,6 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
private static final Integer PROJECT_CODE_LENGTH = 6;
|
||||
|
||||
|
||||
|
||||
public static final String INDUSTRY_TYPE_YYS_DICT_TYPE = "bg_yys";
|
||||
public static final String INDUSTRY_TYPE_DICT_TYPE = "bg_hysy";
|
||||
public static final String BG_TYPE_DICT_TYPE = "bg_type";
|
||||
|
|
@ -108,7 +120,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
projectInfo.setProjectWorkProgressList(projectWorkProgresses);
|
||||
//查询操作日志信息
|
||||
List<ProjectOperateLog> projectOperateLogs = operateLogService.selectProjectOperateLogListByProjectId(projectInfo.getId());
|
||||
projectOperateLogs=projectOperateLogs.stream().filter(item->{
|
||||
projectOperateLogs = projectOperateLogs.stream().filter(item -> {
|
||||
if (ShiroUtils.getSysUser().isAdmin()) {
|
||||
return ProjectOperateLog.LogTypeEnum.DETAIL.getValue().equals(item.getLogType());
|
||||
}
|
||||
|
|
@ -119,6 +131,12 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
if (CollUtil.isNotEmpty(projectPocInfos)) {
|
||||
projectInfo.setProjectPocInfo(projectPocInfos.get(0));
|
||||
}
|
||||
if (StringUtils.isNotEmpty(projectInfo.getFileId())) {
|
||||
OmsFileLog queryFileLog = new OmsFileLog();
|
||||
queryFileLog.setIdList(Arrays.stream(projectInfo.getFileId().split(",")).map(item -> Integer.parseInt(item)).collect(Collectors.toList()));
|
||||
List<OmsFileLog> omsFileLogs = omsFileLogService.queryAll(queryFileLog);
|
||||
projectInfo.setProjectFileList(omsFileLogs);
|
||||
}
|
||||
return projectInfo;
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +150,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
@DataScope(deptAlias = "t3", userAlias = "t3")
|
||||
public List<ProjectInfo> selectProjectInfoList(ProjectInfo projectInfo) {
|
||||
List<ProjectInfo> projectInfos = projectInfoMapper.selectProjectInfoList(projectInfo);
|
||||
if (CollUtil.isEmpty(projectInfos)){
|
||||
if (CollUtil.isEmpty(projectInfos)) {
|
||||
return projectInfos;
|
||||
}
|
||||
//处理客户信息地址
|
||||
|
|
@ -166,7 +184,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
} else {
|
||||
info.setHighlight(false);
|
||||
}
|
||||
info.setCollect(projectCollectMap.getOrDefault(info.getId(),"0"));
|
||||
info.setCollect(projectCollectMap.getOrDefault(info.getId(), "0"));
|
||||
}
|
||||
return projectInfos;
|
||||
}
|
||||
|
|
@ -268,7 +286,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
saveOtherInfo(projectInfo);
|
||||
// 记录操作日志
|
||||
recordOperationLogs(projectInfo, oldProjectInfo);
|
||||
if (CollUtil.isNotEmpty(projectOrderInfos)){
|
||||
if (CollUtil.isNotEmpty(projectOrderInfos)) {
|
||||
ProjectOrderInfo projectOrderInfo = projectOrderInfos.get(0);
|
||||
ProjectOrderInfo update = new ProjectOrderInfo();
|
||||
update.setId(projectOrderInfo.getId());
|
||||
|
|
@ -367,7 +385,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
operateLogService.insertProjectOperateLog(operateLog);
|
||||
//记录type
|
||||
}
|
||||
if (logSimpleContent.length() > 0){
|
||||
if (logSimpleContent.length() > 0) {
|
||||
ProjectOperateLog operateLog = new ProjectOperateLog();
|
||||
operateLog.setProjectId(projectInfo.getId());
|
||||
operateLog.setOperateLog(logSimpleContent.toString());
|
||||
|
|
@ -388,21 +406,21 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
return ++index;
|
||||
}
|
||||
if (oldInfo != null) {
|
||||
index=compareField(logContent, index, "POC服务器配置", oldInfo.getServerConfig(), info.getServerConfig());
|
||||
index=compareField(logContent, index, "POC云桌面版本", oldInfo.getVdiVersion(), info.getVdiVersion());
|
||||
index=compareField(logContent, index, "POC配置终端", oldInfo.getTerminalConfig(), info.getTerminalConfig());
|
||||
index=compareField(logContent, index, "POC操作系统", oldInfo.getOperateSystem(), info.getOperateSystem());
|
||||
index=compareField(logContent, index, "POC H3C接口人", oldInfo.getH3cPerson(), info.getH3cPerson());
|
||||
index=compareField(logContent, index, "POC H3C TEL", oldInfo.getH3cPhone(), info.getH3cPhone());
|
||||
index=compareField(logContent, index, "POC汇智接口人", oldInfo.getHzInterfacePerson(), info.getHzInterfacePerson());
|
||||
index=compareField(logContent, index, "POC汇智 TEL", oldInfo.getHzInterfacePhone(), info.getHzInterfacePhone());
|
||||
index=compareField(logContent, index, "POC研发接口人", oldInfo.getProcessPerson(), info.getProcessPerson());
|
||||
index=compareField(logContent, index, "POC研发 TEL", oldInfo.getProcessPhone(), info.getProcessPhone());
|
||||
index=compareField(logContent, index, "POC现场接口人", oldInfo.getHandlePerson(), info.getHandlePerson());
|
||||
index=compareField(logContent, index, "POC现场 TEL", oldInfo.getHandlePhone(), info.getHandlePhone());
|
||||
index=compareField(logContent, index, "POC启动时间", formatterDate(oldInfo.getStartDate()), formatterDate(info.getStartDate()));
|
||||
index=compareField(logContent, index, "POC预计完成时间", formatterDate(oldInfo.getPlanFinishTime()), formatterDate(info.getPlanFinishTime()));
|
||||
index=compareField(logContent, index, "POC实际完成时间", formatterDate(oldInfo.getRealFinishTime()), formatterDate(info.getRealFinishTime()));
|
||||
index = compareField(logContent, index, "POC服务器配置", oldInfo.getServerConfig(), info.getServerConfig());
|
||||
index = compareField(logContent, index, "POC云桌面版本", oldInfo.getVdiVersion(), info.getVdiVersion());
|
||||
index = compareField(logContent, index, "POC配置终端", oldInfo.getTerminalConfig(), info.getTerminalConfig());
|
||||
index = compareField(logContent, index, "POC操作系统", oldInfo.getOperateSystem(), info.getOperateSystem());
|
||||
index = compareField(logContent, index, "POC H3C接口人", oldInfo.getH3cPerson(), info.getH3cPerson());
|
||||
index = compareField(logContent, index, "POC H3C TEL", oldInfo.getH3cPhone(), info.getH3cPhone());
|
||||
index = compareField(logContent, index, "POC汇智接口人", oldInfo.getHzInterfacePerson(), info.getHzInterfacePerson());
|
||||
index = compareField(logContent, index, "POC汇智 TEL", oldInfo.getHzInterfacePhone(), info.getHzInterfacePhone());
|
||||
index = compareField(logContent, index, "POC研发接口人", oldInfo.getProcessPerson(), info.getProcessPerson());
|
||||
index = compareField(logContent, index, "POC研发 TEL", oldInfo.getProcessPhone(), info.getProcessPhone());
|
||||
index = compareField(logContent, index, "POC现场接口人", oldInfo.getHandlePerson(), info.getHandlePerson());
|
||||
index = compareField(logContent, index, "POC现场 TEL", oldInfo.getHandlePhone(), info.getHandlePhone());
|
||||
index = compareField(logContent, index, "POC启动时间", formatterDate(oldInfo.getStartDate()), formatterDate(info.getStartDate()));
|
||||
index = compareField(logContent, index, "POC预计完成时间", formatterDate(oldInfo.getPlanFinishTime()), formatterDate(info.getPlanFinishTime()));
|
||||
index = compareField(logContent, index, "POC实际完成时间", formatterDate(oldInfo.getRealFinishTime()), formatterDate(info.getRealFinishTime()));
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
|
@ -413,6 +431,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
}
|
||||
return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 比较产品信息列表并生成日志内容
|
||||
*
|
||||
|
|
@ -435,7 +454,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
index++;
|
||||
}
|
||||
//删除
|
||||
List<String> deleteCode =CollUtil.isEmpty(oldList) ? Collections.emptyList() : oldList.stream().filter(item -> !newMap.containsKey(item.getId())).map(ProjectProductInfo::getProductBomCode).collect(Collectors.toList());
|
||||
List<String> deleteCode = CollUtil.isEmpty(oldList) ? Collections.emptyList() : oldList.stream().filter(item -> !newMap.containsKey(item.getId())).map(ProjectProductInfo::getProductBomCode).collect(Collectors.toList());
|
||||
if (CollUtil.isNotEmpty(deleteCode)) {
|
||||
logContent.append(index).append(".产品删除").append(type).append(":").append(String.join(",", deleteCode)).append("\n");
|
||||
index++;
|
||||
|
|
@ -520,7 +539,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
enrichProjectData(projectInfos);
|
||||
|
||||
// 计算各类产品的最大数量
|
||||
List<Integer> maxCounts= calculateMaxProductCounts(projectInfos);
|
||||
List<Integer> maxCounts = calculateMaxProductCounts(projectInfos);
|
||||
int maxSoftware = maxCounts.get(0);
|
||||
int maxHardware = maxCounts.get(1);
|
||||
int maxMaintenance = maxCounts.get(2);
|
||||
|
|
@ -545,7 +564,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
StringBuilder authSql = new StringBuilder();
|
||||
authSql.append(" and t1.id in (select project_id from project_order_info where ");
|
||||
authSql.append(StringUtils.format(" order_status in ('{}','{}')"
|
||||
,ProjectOrderInfo.OrderStatus.APPROVE_COMPLETE.getCode(),ProjectOrderInfo.OrderStatus.WAIT_APPROVE.getCode()));
|
||||
, ProjectOrderInfo.OrderStatus.APPROVE_COMPLETE.getCode(), ProjectOrderInfo.OrderStatus.WAIT_APPROVE.getCode()));
|
||||
if ("总代".equals(sysUser.getDept().getDeptName())) {
|
||||
//总代
|
||||
authSql.append(" and ( ");
|
||||
|
|
@ -558,7 +577,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
}
|
||||
authSql.append(" ) ");
|
||||
dto.setAuthSql(authSql.toString());
|
||||
}else{
|
||||
} else {
|
||||
dto.setAuthSql(null);
|
||||
}
|
||||
|
||||
|
|
@ -604,15 +623,185 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
|
||||
@Override
|
||||
public int editJoinTrial(ProjectInfo projectInfo) {
|
||||
if ("0".equals(projectInfo.getJointTrial())){
|
||||
if ("0".equals(projectInfo.getJointTrial())) {
|
||||
List<ProjectOrderInfo> projectOrderInfos = orderInfoService.selectProjectOrderInfoByProjectId(Collections.singletonList(projectInfo.getId()));
|
||||
if (CollUtil.isNotEmpty(projectOrderInfos)){
|
||||
if (CollUtil.isNotEmpty(projectOrderInfos)) {
|
||||
throw new ServiceException("已生成项目,无法取消会审");
|
||||
}
|
||||
}
|
||||
return projectInfoMapper.updateProjectInfo(projectInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] exportSingleJoinTrial(ProjectInfo projectInfo) {
|
||||
try {
|
||||
// 加载模板文件 - 模板文件位于 ruoyi-admin/src/main/resources/wordTemplate/
|
||||
String localPath = RuoYiConfig.getExcelTemplate() + File.separator + "jointTrialTemplate.docx";
|
||||
InputStream templateStream = Files.newInputStream(Paths.get(localPath));
|
||||
if (templateStream == null) {
|
||||
throw new ServiceException("模板文件不存在,请确认 wordTemplate/orderDownloadTemplate.docx 文件是否在资源目录中");
|
||||
}
|
||||
XWPFDocument document = new XWPFDocument(templateStream);
|
||||
|
||||
// 替换文档中的占位符
|
||||
replaceTextInDocument(document, projectInfo);
|
||||
|
||||
// 将文档写入字节数组
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
document.write(baos);
|
||||
document.close();
|
||||
templateStream.close();
|
||||
|
||||
return baos.toByteArray();
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("导出合同模板失败", e);
|
||||
throw new ServiceException("导出合同模板失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void replaceTextInDocument(XWPFDocument document, ProjectInfo projectInfo) {
|
||||
// 替换段落中的文本
|
||||
for (XWPFParagraph paragraph : document.getParagraphs()) {
|
||||
replaceTextInParagraph(paragraph, projectInfo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void replaceTextInParagraph(XWPFParagraph paragraph, ProjectInfo projectInfo) {
|
||||
String text = paragraph.getText();
|
||||
if (text != null && text.contains("${")) {
|
||||
// 创建替换映射
|
||||
Map<String, String> replacements = createReplacementMap(projectInfo);
|
||||
|
||||
// 替换文本
|
||||
for (Map.Entry<String, String> entry : replacements.entrySet()) {
|
||||
String placeholder = "${" + entry.getKey() + "}";
|
||||
if (text.contains(placeholder)) {
|
||||
text = text.replace(placeholder, entry.getValue() != null ? entry.getValue() : "");
|
||||
}
|
||||
}
|
||||
|
||||
// 清除原有运行并设置新文本
|
||||
for (int i = paragraph.getRuns().size() - 1; i >= 0; i--) {
|
||||
paragraph.removeRun(i);
|
||||
}
|
||||
|
||||
XWPFRun run = paragraph.createRun();
|
||||
run.setText(text);
|
||||
}
|
||||
}
|
||||
private Map<String, String> createReplacementMap(ProjectInfo projectInfo) {
|
||||
Map<String, String> replacements = new HashMap<>();
|
||||
|
||||
// 基本订单信息
|
||||
replacements.put("projectCode", projectInfo.getProjectCode());
|
||||
replacements.put("projectName", projectInfo.getProjectName());
|
||||
// 金额信息
|
||||
replacements.put("customerName", projectInfo.getCustomerName());
|
||||
replacements.put("customerUserName", StrUtil.isEmpty(projectInfo.getCustomerUserName())?" ":projectInfo.getCustomerUserName());
|
||||
replacements.put("customerPhone", projectInfo.getCustomerPhone());
|
||||
replacements.put("countryProduct", formatterStr(projectInfo.getCountryProduct()));
|
||||
replacements.put("poc", formatterStr(projectInfo.getPoc()));
|
||||
replacements.put("hzSupportUserName", projectInfo.getHzSupportUserName());
|
||||
|
||||
replacements.put("projectDesc", projectInfo.getProjectDesc());
|
||||
// 责任人信息
|
||||
replacements.put("softwareInfo", projectInfo.getSoftwareInfo());
|
||||
replacements.put("hardwareInfo", projectInfo.getHardwareInfo());
|
||||
|
||||
// 进货商信息
|
||||
replacements.put("terminalPeripheral", projectInfo.getTerminalPeripheral());
|
||||
replacements.put("serverConfiguration", projectInfo.getServerConfiguration());
|
||||
replacements.put("managementVersion", projectInfo.getManagementVersion());
|
||||
replacements.put("desktopVmOsVersion", projectInfo.getDesktopVmOsVersion());
|
||||
replacements.put("vmSpecQuantity", projectInfo.getVmSpecQuantity());
|
||||
replacements.put("keyProblem", projectInfo.getKeyProblem());
|
||||
replacements.put("jointTrialResult", projectInfo.getJointTrialResult());
|
||||
|
||||
return replacements;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String exportJoinTrial(ProjectInfo projectInfo) {
|
||||
try {
|
||||
projectInfo.setJointTrial("1");
|
||||
// 获取项目信息列表
|
||||
List<ProjectInfo> projectInfos = fetchProjectInfos(projectInfo);
|
||||
|
||||
|
||||
|
||||
// 构建 Excel 表头和数据
|
||||
List<List<String>> header = buildExcelJointTrialHeader();
|
||||
List<List<String>> data = buildExcelJointTrialData(projectInfos);
|
||||
|
||||
// 导出 Excel 文件
|
||||
return writeExcelToFile(header, data);
|
||||
} catch (Exception e) {
|
||||
log.error("导出项目信息失败", e);
|
||||
throw new ServiceException("导出项目信息失败,请稍后重试");
|
||||
}
|
||||
}
|
||||
|
||||
private List<List<String>> buildExcelJointTrialData(List<ProjectInfo> projectInfos) {
|
||||
List<List<String>> dataList = new ArrayList<>();
|
||||
for (ProjectInfo info : projectInfos) {
|
||||
List<String> row = new ArrayList<>();
|
||||
// 添加基础字段
|
||||
row.add(info.getProjectCode());
|
||||
row.add(info.getProjectName());
|
||||
row.add(info.getCustomerName());
|
||||
row.add(info.getCustomerUserName());
|
||||
row.add(info.getCustomerPhone());
|
||||
row.add(info.getHzSupportUserName());
|
||||
row.add(formatterStr(info.getCountryProduct()));
|
||||
row.add(formatterStr(info.getPoc()));
|
||||
row.add(info.getProjectDesc());
|
||||
row.add(info.getSoftwareInfo());
|
||||
row.add(info.getHardwareInfo());
|
||||
row.add(info.getTerminalPeripheral());
|
||||
row.add(info.getServerConfiguration());
|
||||
row.add(info.getManagementVersion());
|
||||
row.add(info.getDesktopVmOsVersion());
|
||||
row.add(info.getVmSpecQuantity());
|
||||
|
||||
row.add(info.getKeyProblem());
|
||||
row.add(info.getJointTrialResult());
|
||||
|
||||
dataList.add(row);
|
||||
}
|
||||
return dataList;
|
||||
}
|
||||
|
||||
private List<List<String>> buildExcelJointTrialHeader() {
|
||||
|
||||
List<List<String>> headerList = new ArrayList<>();
|
||||
headerList.add(Collections.singletonList("项目编号"));
|
||||
headerList.add(Collections.singletonList("项目名称"));
|
||||
headerList.add(Collections.singletonList("最终客户"));
|
||||
headerList.add(Collections.singletonList("客户联系人"));
|
||||
headerList.add(Collections.singletonList("客户 TEL"));
|
||||
headerList.add(Collections.singletonList("汇智负责人"));
|
||||
headerList.add(Collections.singletonList("是否国产"));
|
||||
headerList.add(Collections.singletonList("poc"));
|
||||
headerList.add(Collections.singletonList("项目描述"));
|
||||
headerList.add(Collections.singletonList("授权"));
|
||||
headerList.add(Collections.singletonList("终端"));
|
||||
headerList.add(Collections.singletonList("其它终端、外设"));
|
||||
headerList.add(Collections.singletonList("服务器"));
|
||||
headerList.add(Collections.singletonList("管理端版本"));
|
||||
headerList.add(Collections.singletonList("桌面虚拟机OS版本"));
|
||||
headerList.add(Collections.singletonList("虚拟机规格、数量"));
|
||||
headerList.add(Collections.singletonList("技术风险与问题"));
|
||||
headerList.add(Collections.singletonList("会审结论"));
|
||||
|
||||
return headerList;
|
||||
|
||||
}
|
||||
|
||||
private List<ProjectInfo> fetchProjectInfos(ProjectInfo projectInfo) {
|
||||
projectInfo.setCurrentUserId(ShiroUtils.getUserId());
|
||||
List<ProjectInfo> projectInfos = projectInfoMapper.selectProjectInfoList(projectInfo);
|
||||
|
|
@ -626,7 +815,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
Map<Long, String> projectCollectMap = projectUserCollectInfos.stream().collect(
|
||||
Collectors.toMap(ProjectUserCollectInfo::getProjectId, ProjectUserCollectInfo::getCollect, (v1, v2) -> v1));
|
||||
projectInfos.forEach(item -> {
|
||||
item.setCollect(projectCollectMap.getOrDefault(item.getId(),"0"));
|
||||
item.setCollect(projectCollectMap.getOrDefault(item.getId(), "0"));
|
||||
});
|
||||
return projectInfos;
|
||||
}
|
||||
|
|
@ -710,7 +899,6 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
public static class CustomColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
|
||||
int columnIndex = cell.getColumnIndex();
|
||||
|
|
@ -729,7 +917,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
}
|
||||
}
|
||||
|
||||
public List<List<String>> buildExcelHeader( int maxSoftware, int maxHardware, int maxMaintenance, int maxWorkIndex) {
|
||||
public List<List<String>> buildExcelHeader(int maxSoftware, int maxHardware, int maxMaintenance, int maxWorkIndex) {
|
||||
List<List<String>> headerList = new ArrayList<>();
|
||||
headerList.add(Collections.singletonList("项目编号"));
|
||||
headerList.add(Collections.singletonList("项目名称"));
|
||||
|
|
@ -788,7 +976,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
headerList.add(Collections.singletonList("产品总价"));
|
||||
|
||||
|
||||
for (int i = 1; i <=maxWorkIndex; i++) {
|
||||
for (int i = 1; i <= maxWorkIndex; i++) {
|
||||
headerList.add(Collections.singletonList("变更内容" + i));
|
||||
headerList.add(Collections.singletonList("变更人" + i));
|
||||
headerList.add(Collections.singletonList("变更时间" + i));
|
||||
|
|
@ -812,13 +1000,13 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
row.add(info.getCustomerName());
|
||||
row.add(info.getCustomerUserName());
|
||||
row.add(info.getCustomerPhone());
|
||||
row.add(DictUtils.getDictLabel("operate_institution",info.getOperateInstitution()));
|
||||
row.add(DictUtils.getDictLabel("operate_institution", info.getOperateInstitution()));
|
||||
row.add(info.getH3cPerson());
|
||||
row.add(info.getH3cPhone());
|
||||
row.add(info.getPartnerName());
|
||||
row.add(info.getPartnerUserName());
|
||||
row.add(info.getContactWay());
|
||||
row.add(info.getEstimatedAmount()!=null?info.getEstimatedAmount().toString():"");
|
||||
row.add(info.getEstimatedAmount() != null ? info.getEstimatedAmount().toString() : "");
|
||||
row.add(DateUtil.format(info.getEstimatedOrderTime(), "yyyy-MM-dd"));
|
||||
row.add(formatterStr(info.getPoc()));
|
||||
row.add(info.getCompetitor());
|
||||
|
|
@ -827,14 +1015,14 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
row.add(info.getProjectDesc());
|
||||
row.add(info.getServerConfiguration());
|
||||
row.add(DateUtil.format(info.getUpdateTime(), "yyyy-MM-dd"));
|
||||
row.add("1".equals(info.getCollect())?"是":"否");
|
||||
row.add("1".equals(info.getJointTrial())?"是":"否");
|
||||
row.add("1".equals(info.getCollect()) ? "是" : "否");
|
||||
row.add("1".equals(info.getJointTrial()) ? "是" : "否");
|
||||
BigDecimal totalPrice = BigDecimal.ZERO;
|
||||
|
||||
// 添加软件产品列
|
||||
for (int i = 0; i < maxSoftware; i++) {
|
||||
if (CollUtil.isNotEmpty(info.getSoftwareProjectProductInfoList()) && i < info.getSoftwareProjectProductInfoList().size()) {
|
||||
totalPrice= addProductRow(info.getSoftwareProjectProductInfoList().get(i), row, totalPrice);
|
||||
totalPrice = addProductRow(info.getSoftwareProjectProductInfoList().get(i), row, totalPrice);
|
||||
} else {
|
||||
addProductRow(null, row, totalPrice);
|
||||
}
|
||||
|
|
@ -843,7 +1031,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
// 添加终端产品列
|
||||
for (int i = 0; i < maxHardware; i++) {
|
||||
if (CollUtil.isNotEmpty(info.getHardwareProjectProductInfoList()) && i < info.getHardwareProjectProductInfoList().size()) {
|
||||
totalPrice=addProductRow(info.getHardwareProjectProductInfoList().get(i), row, totalPrice);
|
||||
totalPrice = addProductRow(info.getHardwareProjectProductInfoList().get(i), row, totalPrice);
|
||||
} else {
|
||||
addProductRow(null, row, totalPrice);
|
||||
}
|
||||
|
|
@ -852,7 +1040,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
// 添加服务产品列
|
||||
for (int i = 0; i < maxMaintenance; i++) {
|
||||
if (CollUtil.isNotEmpty(info.getMaintenanceProjectProductInfoList()) && i < info.getMaintenanceProjectProductInfoList().size()) {
|
||||
totalPrice=addProductRow(info.getMaintenanceProjectProductInfoList().get(i), row, totalPrice);
|
||||
totalPrice = addProductRow(info.getMaintenanceProjectProductInfoList().get(i), row, totalPrice);
|
||||
} else {
|
||||
addProductRow(null, row, totalPrice);
|
||||
}
|
||||
|
|
@ -880,12 +1068,13 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
|
|||
return dataList;
|
||||
}
|
||||
|
||||
private String formatterStr(String value){
|
||||
if (StringUtils.isEmpty(value)){
|
||||
private String formatterStr(String value) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
return "";
|
||||
}
|
||||
return "0".equals(value)?"否":"是";
|
||||
return "1".equals(value) ? "是":"否";
|
||||
}
|
||||
|
||||
private static BigDecimal addProductRow(ProjectProductInfo productInfo, List<String> row, BigDecimal totalPrice) {
|
||||
if (productInfo == null) {
|
||||
row.add("");
|
||||
|
|
|
|||
|
|
@ -30,6 +30,13 @@
|
|||
<if test="id != null">
|
||||
and id = #{id}
|
||||
</if>
|
||||
<if test="idList != null">
|
||||
and id in (
|
||||
<foreach item="item" index="index" collection="idList" separator=",">
|
||||
#{item}
|
||||
</foreach>
|
||||
)
|
||||
</if>
|
||||
<if test="newFilename != null and newFilename != ''">
|
||||
and new_filename = #{newFilename}
|
||||
</if>
|
||||
|
|
@ -141,6 +148,18 @@
|
|||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<insert id="insertBatch">
|
||||
INSERT INTO oms_file_log
|
||||
(new_filename,file_name,file_path,file_size,file_type,create_by,
|
||||
create_time, update_by, update_time, remark,project_id)
|
||||
|
||||
values
|
||||
<foreach item="item" index="index" collection="list" separator="," open="(" close=")">
|
||||
#{item.newFilename}, #{item.fileName}, #{item.filePath}, #{item.fileSize}, #{item.fileType},
|
||||
#{item.createBy},
|
||||
#{item.createTime}, #{item.updateBy}, #{item.updateTime}, #{item.remark},#{item.projectId}
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<!--通过主键修改数据-->
|
||||
<update id="update">
|
||||
|
|
|
|||
|
|
@ -33,12 +33,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<result property="updateTime" column="update_time" />
|
||||
<result property="bgProperty" column="bg_property" />
|
||||
<result property="jointTrial" column="joint_trial" />
|
||||
<result property="softwareInfo" column="software_info" />
|
||||
<result property="hardwareInfo" column="hardware_info" />
|
||||
<result property="terminalPeripheral" column="terminal_peripheral" />
|
||||
<result property="managementVersion" column="management_version" />
|
||||
<result property="desktopVmOsVersion" column="desktop_vm_os_version" />
|
||||
<result property="vmSpecQuantity" column="vm_spec_quantity" />
|
||||
<result property="jointTrialResult" column="joint_trial_result" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectProjectInfoVo">
|
||||
select id, project_code, project_name,bg_property, customer_code, customer_name, industry_type, agent_code, project_stage, project_grasp_degree, hz_support_user, operate_institution
|
||||
, partner_code, partner_name, contact_way, estimated_amount, currency_type, estimated_order_time, estimated_deliver_time, competitor, country_product, server_configuration
|
||||
, key_problem, project_desc, create_by, create_time, update_by, update_time,customer_user_name,customer_phone,partner_email,partner_user_name,h3c_person,h3c_phone,poc,joint_trial from project_info t1
|
||||
, partner_code, partner_name, contact_way, estimated_amount, currency_type, estimated_order_time, estimated_deliver_time, competitor, country_product, server_configuration,file_id
|
||||
, key_problem, project_desc, create_by, create_time, update_by, update_time,customer_user_name,customer_phone,partner_email,partner_user_name,h3c_person,h3c_phone,poc,joint_trial,software_info,hardware_info,terminal_peripheral,management_version,desktop_vm_os_version,vm_spec_quantity,joint_trial_result from project_info t1
|
||||
</sql>
|
||||
<sql id="selectRelationProjectInfoVo">
|
||||
select t1.id,
|
||||
|
|
@ -70,6 +77,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
t1.update_by,
|
||||
t1.update_time,
|
||||
t1.joint_trial,
|
||||
t1.software_info,
|
||||
t1.hardware_info,
|
||||
t1.terminal_peripheral,
|
||||
t1.management_version,
|
||||
t1.desktop_vm_os_version,
|
||||
t1.vm_spec_quantity,
|
||||
t1.joint_trial_result,
|
||||
t1.file_id,
|
||||
t1.customer_user_name,t1.customer_phone,t1.partner_user_name,t1.h3c_person,t1.poc,t1.h3c_phone,
|
||||
t2.agent_name,t2.contact_email,t2.contact_phone,t2.contact_person,
|
||||
t3.user_name as hz_support_user_name,
|
||||
|
|
@ -97,6 +112,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="agentName != null and agentName != ''"> and t2.agent_name like concat('%', #{agentName}, '%')</if>
|
||||
<if test="customerName != null and customerName != ''"> and t1.customer_name like concat('%', #{customerName}, '%')</if>
|
||||
<if test="industryType != null and industryType != ''"> and t1.industry_type = #{industryType}</if>
|
||||
<if test="industryTypeList != null and industryTypeList.size>0"> and t1.industry_type in
|
||||
<foreach collection="industryTypeList" item="item" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="bgProperty != null and bgProperty != ''"> and t1.bg_property = #{bgProperty}</if>
|
||||
<if test="jointTrial != null and jointTrial != ''"> and t1.joint_trial = #{jointTrial}</if>
|
||||
<if test="collect != null and collect != ''">
|
||||
|
|
@ -258,6 +278,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="updateBy != null">update_by,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="jointTrial != null and jointTrial != ''"> joint_trial ,</if>
|
||||
<if test="softwareInfo != null">software_info,</if>
|
||||
<if test="hardwareInfo != null">hardware_info,</if>
|
||||
<if test="terminalPeripheral != null">terminal_peripheral,</if>
|
||||
<if test="managementVersion != null">management_version,</if>
|
||||
<if test="desktopVmOsVersion != null">desktop_vm_os_version,</if>
|
||||
<if test="vmSpecQuantity != null">vm_spec_quantity,</if>
|
||||
<if test="jointTrialResult != null">joint_trial_result,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="projectCode != null">#{projectCode},</if>
|
||||
|
|
@ -295,6 +322,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="updateBy != null">#{updateBy},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="jointTrial != null and jointTrial != ''"> #{jointTrial},</if>
|
||||
<if test="softwareInfo != null">#{softwareInfo},</if>
|
||||
<if test="hardwareInfo != null">#{hardwareInfo},</if>
|
||||
<if test="terminalPeripheral != null">#{terminalPeripheral},</if>
|
||||
<if test="managementVersion != null">#{managementVersion},</if>
|
||||
<if test="desktopVmOsVersion != null">#{desktopVmOsVersion},</if>
|
||||
<if test="vmSpecQuantity != null">#{vmSpecQuantity},</if>
|
||||
<if test="jointTrialResult != null">#{jointTrialResult},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<update id="updateCustomerCodeByCode">
|
||||
|
|
@ -320,6 +354,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="hzSupportUser != null">hz_support_user = #{hzSupportUser},</if>
|
||||
<if test="operateInstitution != null">operate_institution = #{operateInstitution},</if>
|
||||
partner_code = #{partnerCode},
|
||||
file_id = #{fileId},
|
||||
<if test="partnerName != null">partner_name = #{partnerName},</if>
|
||||
<if test="partnerUserName != null">partner_user_name = #{partnerUserName},</if>
|
||||
<if test="partnerEmail != null">partner_email=#{partnerEmail},</if>
|
||||
|
|
@ -338,6 +373,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="jointTrial != null and jointTrial != ''"> joint_trial = #{jointTrial},</if>
|
||||
<if test="softwareInfo != null">software_info = #{softwareInfo},</if>
|
||||
<if test="hardwareInfo != null">hardware_info = #{hardwareInfo},</if>
|
||||
<if test="terminalPeripheral != null">terminal_peripheral = #{terminalPeripheral},</if>
|
||||
<if test="managementVersion != null">management_version = #{managementVersion},</if>
|
||||
<if test="desktopVmOsVersion != null">desktop_vm_os_version = #{desktopVmOsVersion},</if>
|
||||
<if test="vmSpecQuantity != null">vm_spec_quantity = #{vmSpecQuantity},</if>
|
||||
<if test="jointTrialResult != null">joint_trial_result = #{jointTrialResult},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
|
|
|||
Loading…
Reference in New Issue