feat(quotation): 新增报价单详情页面并完善相关功能
- 新增报价单详情页面实现查看功能 - 添加选择报价单组件支持项目关联报价单 - 更新权限配置将base模块改为sip模块 - 在项目表中新增合作商系统用户ID字段 - 完善报价单控制器的权限注解 - 优化报价单导出Excel格式和样式 - 修复查询条件中的表别名问题 - 添加省代服务产品类型支持dev_1.0.1^2
parent
50ee54d6ef
commit
a7f7a29d74
|
|
@ -0,0 +1,143 @@
|
||||||
|
<template>
|
||||||
|
<el-drawer
|
||||||
|
title="报价单详情"
|
||||||
|
:visible.sync="visible"
|
||||||
|
direction="rtl"
|
||||||
|
size="80%"
|
||||||
|
:before-close="handleClose"
|
||||||
|
append-to-body
|
||||||
|
>
|
||||||
|
<div class="detail-container" v-loading="loading">
|
||||||
|
<!-- Basic Info -->
|
||||||
|
<el-divider content-position="left">基本信息</el-divider>
|
||||||
|
<el-descriptions :column="2" border size="medium">
|
||||||
|
<el-descriptions-item label="报价单号">{{ form.quotationCode }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="报价单名称">{{ form.quotationName }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="币种">
|
||||||
|
<dict-tag :options="dict.type.currency_type" :value="form.amountType"/>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="代表处">{{ agentName }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="客户名称">{{ form.customerName }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="状态">{{ form.quotationStatus }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="创建时间">{{ parseTime(form.createTime) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="备注" :span="2">{{ form.remark }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
|
||||||
|
<div v-if="form.quotationCode || catalogueTotalPrice > 0 || discountedTotalPrice > 0" style="margin-top: 20px;">
|
||||||
|
<el-row type="flex" justify="space-between" style="margin-bottom: 20px; font-size: 14px;">
|
||||||
|
<el-col :span="24" style="text-align: right;">
|
||||||
|
<span v-if="catalogueTotalPrice > 0" style="margin-right: 20px;">
|
||||||
|
<span style="font-weight: bold;">目录总价:</span>{{ formatAmount(catalogueTotalPrice) }}
|
||||||
|
</span>
|
||||||
|
<span v-if="discountedTotalPrice > 0">
|
||||||
|
<span style="font-weight: bold;">折后总价:</span>{{ formatAmount(discountedTotalPrice) }}
|
||||||
|
</span>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Config Info -->
|
||||||
|
<product-config :value="form" readonly />
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getQuotation } from "@/api/base/quotation";
|
||||||
|
import ProductConfig from "@/views/project/info/ProductConfig";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "QuotationDetail",
|
||||||
|
components: { ProductConfig },
|
||||||
|
dicts: ['currency_type'],
|
||||||
|
props: {
|
||||||
|
agentOptions: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
visible: false,
|
||||||
|
loading: false,
|
||||||
|
form: {
|
||||||
|
softwareProjectProductInfoList: [],
|
||||||
|
hardwareProjectProductInfoList: [],
|
||||||
|
maintenanceProjectProductInfoList: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
agentName() {
|
||||||
|
if (!this.form.agentCode || !this.agentOptions) return this.form.agentCode;
|
||||||
|
const agent = this.agentOptions.find(item => item.agentCode === this.form.agentCode);
|
||||||
|
return agent ? agent.agentName : this.form.agentCode;
|
||||||
|
},
|
||||||
|
catalogueTotalPrice() {
|
||||||
|
let total = 0;
|
||||||
|
const lists = [
|
||||||
|
this.form.softwareProjectProductInfoList,
|
||||||
|
this.form.hardwareProjectProductInfoList,
|
||||||
|
this.form.maintenanceProjectProductInfoList
|
||||||
|
];
|
||||||
|
lists.forEach(list => {
|
||||||
|
if (list && list.length > 0) {
|
||||||
|
list.forEach(item => {
|
||||||
|
total += Number(item.catalogueAllPrice) || 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return total;
|
||||||
|
},
|
||||||
|
discountedTotalPrice() {
|
||||||
|
let total = 0;
|
||||||
|
const lists = [
|
||||||
|
this.form.softwareProjectProductInfoList,
|
||||||
|
this.form.hardwareProjectProductInfoList,
|
||||||
|
this.form.maintenanceProjectProductInfoList
|
||||||
|
];
|
||||||
|
lists.forEach(list => {
|
||||||
|
if (list && list.length > 0) {
|
||||||
|
list.forEach(item => {
|
||||||
|
total += Number(item.allPrice) || 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
open(id) {
|
||||||
|
this.visible = true;
|
||||||
|
this.getDetail(id);
|
||||||
|
},
|
||||||
|
getDetail(id) {
|
||||||
|
this.loading = true;
|
||||||
|
getQuotation(id).then(response => {
|
||||||
|
this.form = response.data;
|
||||||
|
// Ensure lists are arrays
|
||||||
|
this.form.softwareProjectProductInfoList = this.form.softwareProjectProductInfoList || [];
|
||||||
|
this.form.hardwareProjectProductInfoList = this.form.hardwareProjectProductInfoList || [];
|
||||||
|
this.form.maintenanceProjectProductInfoList = this.form.maintenanceProjectProductInfoList || [];
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleClose(done) {
|
||||||
|
this.visible = false;
|
||||||
|
if (done) done();
|
||||||
|
},
|
||||||
|
formatAmount(value) {
|
||||||
|
if (value === null || value === undefined) return '';
|
||||||
|
return Number(value).toLocaleString('en-US', {
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.detail-container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -50,7 +50,7 @@
|
||||||
icon="el-icon-plus"
|
icon="el-icon-plus"
|
||||||
size="mini"
|
size="mini"
|
||||||
@click="handleAdd"
|
@click="handleAdd"
|
||||||
v-hasPermi="['base:quotation:add']"
|
v-hasPermi="['sip:quotation:add']"
|
||||||
>新增</el-button>
|
>新增</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
|
|
@ -61,7 +61,7 @@
|
||||||
size="mini"
|
size="mini"
|
||||||
:disabled="single"
|
:disabled="single"
|
||||||
@click="handleUpdate"
|
@click="handleUpdate"
|
||||||
v-hasPermi="['base:quotation:edit']"
|
v-hasPermi="['sip:quotation:update']"
|
||||||
>修改</el-button>
|
>修改</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
size="mini"
|
size="mini"
|
||||||
:disabled="multiple"
|
:disabled="multiple"
|
||||||
@click="handleDelete"
|
@click="handleDelete"
|
||||||
v-hasPermi="['base:quotation:remove']"
|
v-hasPermi="['sip:quotation:delete']"
|
||||||
>删除</el-button>
|
>删除</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
|
@ -103,35 +103,34 @@
|
||||||
type="text"
|
type="text"
|
||||||
icon="el-icon-view"
|
icon="el-icon-view"
|
||||||
@click="handleDetail(scope.row)"
|
@click="handleDetail(scope.row)"
|
||||||
v-hasPermi="['base:quotation:query']"
|
|
||||||
>详情</el-button>
|
>详情</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
size="mini"
|
size="mini"
|
||||||
type="text"
|
type="text"
|
||||||
icon="el-icon-edit"
|
icon="el-icon-edit"
|
||||||
@click="handleUpdate(scope.row)"
|
@click="handleUpdate(scope.row)"
|
||||||
v-hasPermi="['base:quotation:edit']"
|
v-hasPermi="['sip:quotation:update']"
|
||||||
>修改</el-button>
|
>修改</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
size="mini"
|
size="mini"
|
||||||
type="text"
|
type="text"
|
||||||
icon="el-icon-document-copy"
|
icon="el-icon-document-copy"
|
||||||
@click="handleCopy(scope.row)"
|
@click="handleCopy(scope.row)"
|
||||||
v-hasPermi="['base:quotation:add']"
|
v-hasPermi="['sip:quotation:add']"
|
||||||
>复制创建</el-button>
|
>复制创建</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
size="mini"
|
size="mini"
|
||||||
type="text"
|
type="text"
|
||||||
icon="el-icon-delete"
|
icon="el-icon-delete"
|
||||||
@click="handleDelete(scope.row)"
|
@click="handleDelete(scope.row)"
|
||||||
v-hasPermi="['base:quotation:remove']"
|
v-hasPermi="['sip:quotation:delete']"
|
||||||
>删除</el-button>
|
>删除</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
size="mini"
|
size="mini"
|
||||||
type="text"
|
type="text"
|
||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
@click="handleExport(scope.row)"
|
@click="handleExport(scope.row)"
|
||||||
v-hasPermi="['base:quotation:export']"
|
v-hasPermi="['sip:quotation:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog title="选择报价单" :visible.sync="visible" :close-on-click-modal="false" width="900px" append-to-body @close="handleClose">
|
||||||
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" @submit.native.prevent>
|
||||||
|
<el-form-item label="报价单号" prop="quotationCode">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.quotationCode"
|
||||||
|
placeholder="请输入报价单号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="报价单名称" prop="quotationName">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.quotationName"
|
||||||
|
placeholder="请输入报价单名称"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="quotationList" @row-click="handleRowClick" highlight-current-row>
|
||||||
|
<el-table-column label="报价单号" align="center" prop="quotationCode" />
|
||||||
|
<el-table-column label="报价单名称" align="center" prop="quotationName" />
|
||||||
|
<el-table-column label="项目编号" align="center" prop="projectCode" />
|
||||||
|
<el-table-column label="报价金额" align="center" prop="discountAmount" />
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-show="total>0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNum"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="handleClose">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { listQuotation } from "@/api/base/quotation";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "SelectQuotation",
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
createBy: {
|
||||||
|
type: String,
|
||||||
|
default: "-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
// 报价单表格数据
|
||||||
|
quotationList: [],
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
createBy: this.createBy,
|
||||||
|
quotationCode: null,
|
||||||
|
quotationName: null,
|
||||||
|
orderByColumn: 'createTime',
|
||||||
|
isAsc: 'desc'
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
visible(val) {
|
||||||
|
if (val) {
|
||||||
|
this.queryParams.createBy = this.createBy||"-1";
|
||||||
|
this.getList();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询报价单列表 */
|
||||||
|
getList() {
|
||||||
|
this.loading = true;
|
||||||
|
listQuotation(this.queryParams).then(response => {
|
||||||
|
this.quotationList = response.rows;
|
||||||
|
this.total = response.total;
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNum = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.resetForm("queryForm");
|
||||||
|
this.handleQuery();
|
||||||
|
},
|
||||||
|
/** 行点击事件 */
|
||||||
|
handleRowClick(row) {
|
||||||
|
this.$emit("quotation-selected", row);
|
||||||
|
this.handleClose();
|
||||||
|
},
|
||||||
|
/** 关闭按钮 */
|
||||||
|
handleClose() {
|
||||||
|
this.$emit("update:visible", false);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -433,7 +433,7 @@
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<select-agent :visible.sync="selectAgentVisible" @agent-selected="handleAgentSelected" />
|
<select-agent :visible.sync="selectAgentVisible" @agent-selected="handleAgentSelected" />
|
||||||
<select-quotation :visible.sync="selectQuotationVisible" @quotation-selected="handleQuotationSelected" />
|
<select-quotation :visible.sync="selectQuotationVisible" :create-by="form.partnerSystemUserId" @quotation-selected="handleQuotationSelected" />
|
||||||
<select-customer :visible.sync="selectCustomerVisible" @customer-selected="handleCustomerSelected" />
|
<select-customer :visible.sync="selectCustomerVisible" @customer-selected="handleCustomerSelected" />
|
||||||
<select-partner :visible.sync="selectPartnerVisible" @partner-selected="handlePartnerSelected" />
|
<select-partner :visible.sync="selectPartnerVisible" @partner-selected="handlePartnerSelected" />
|
||||||
<select-user :visible.sync="selectUserVisible" @user-selected="handleUserSelected" />
|
<select-user :visible.sync="selectUserVisible" @user-selected="handleUserSelected" />
|
||||||
|
|
@ -683,6 +683,7 @@ export default {
|
||||||
partnerName: null,
|
partnerName: null,
|
||||||
partnerCode: null,
|
partnerCode: null,
|
||||||
partnerUserName: null,
|
partnerUserName: null,
|
||||||
|
partnerSystemUserId: null,
|
||||||
contactWay: null,
|
contactWay: null,
|
||||||
estimatedAmount: null,
|
estimatedAmount: null,
|
||||||
estimatedOrderTime: null,
|
estimatedOrderTime: null,
|
||||||
|
|
@ -834,6 +835,7 @@ export default {
|
||||||
if (value === 'h3c') {
|
if (value === 'h3c') {
|
||||||
this.form.partnerName = '新华三';
|
this.form.partnerName = '新华三';
|
||||||
this.form.partnerCode = null;
|
this.form.partnerCode = null;
|
||||||
|
this.form.partnerSystemUserId = null;
|
||||||
}
|
}
|
||||||
if (this.$refs.form) {
|
if (this.$refs.form) {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
|
@ -923,6 +925,8 @@ export default {
|
||||||
this.form.partnerCode = partner.partnerCode;
|
this.form.partnerCode = partner.partnerCode;
|
||||||
this.form.partnerUserName = partner.contactPerson;
|
this.form.partnerUserName = partner.contactPerson;
|
||||||
this.form.contactWay = partner.contactPhone;
|
this.form.contactWay = partner.contactPhone;
|
||||||
|
this.$set(this.form,'partnerSystemUserId', partner.systemUserId);
|
||||||
|
|
||||||
this.selectPartnerVisible = false;
|
this.selectPartnerVisible = false;
|
||||||
},
|
},
|
||||||
openSelectPeople() {
|
openSelectPeople() {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.sip.domain.Quotation;
|
import com.ruoyi.sip.domain.Quotation;
|
||||||
import com.ruoyi.sip.service.IQuotationService;
|
import com.ruoyi.sip.service.IQuotationService;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
@ -28,6 +29,7 @@ public class QuotationController extends BaseController {
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
|
@RequiresPermissions("sip:quotation:list")
|
||||||
public TableDataInfo list(Quotation quotation) {
|
public TableDataInfo list(Quotation quotation) {
|
||||||
startPage();
|
startPage();
|
||||||
List<Quotation> list = quotationService.queryAll(quotation);
|
List<Quotation> list = quotationService.queryAll(quotation);
|
||||||
|
|
@ -43,6 +45,7 @@ public class QuotationController extends BaseController {
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("/insert")
|
@PostMapping("/insert")
|
||||||
|
@RequiresPermissions("sip:quotation:add")
|
||||||
public AjaxResult add(@RequestBody Quotation quotation) {
|
public AjaxResult add(@RequestBody Quotation quotation) {
|
||||||
return toAjax(quotationService.insert(quotation));
|
return toAjax(quotationService.insert(quotation));
|
||||||
}
|
}
|
||||||
|
|
@ -50,6 +53,7 @@ public class QuotationController extends BaseController {
|
||||||
|
|
||||||
|
|
||||||
@PutMapping("/update")
|
@PutMapping("/update")
|
||||||
|
@RequiresPermissions("sip:quotation:update")
|
||||||
public AjaxResult edit(@RequestBody Quotation quotation) {
|
public AjaxResult edit(@RequestBody Quotation quotation) {
|
||||||
return toAjax(quotationService.update(quotation));
|
return toAjax(quotationService.update(quotation));
|
||||||
}
|
}
|
||||||
|
|
@ -57,6 +61,7 @@ public class QuotationController extends BaseController {
|
||||||
|
|
||||||
|
|
||||||
@DeleteMapping("/{id}")
|
@DeleteMapping("/{id}")
|
||||||
|
@RequiresPermissions("sip:quotation:delete")
|
||||||
public AjaxResult remove(@PathVariable("id") Integer id) {
|
public AjaxResult remove(@PathVariable("id") Integer id) {
|
||||||
return toAjax(quotationService.deleteById(id));
|
return toAjax(quotationService.deleteById(id));
|
||||||
}
|
}
|
||||||
|
|
@ -66,10 +71,12 @@ public class QuotationController extends BaseController {
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@DeleteMapping("/remove/batch/{ids}")
|
@DeleteMapping("/remove/batch/{ids}")
|
||||||
|
@RequiresPermissions("sip:quotation:delete")
|
||||||
public AjaxResult batchRemove(@PathVariable("ids") Integer[] ids) {
|
public AjaxResult batchRemove(@PathVariable("ids") Integer[] ids) {
|
||||||
return AjaxResult.success(quotationService.batchRemove(ids));
|
return AjaxResult.success(quotationService.batchRemove(ids));
|
||||||
}
|
}
|
||||||
@GetMapping("/export/single/{id}")
|
@GetMapping("/export/single/{id}")
|
||||||
|
@RequiresPermissions("sip:quotation:export")
|
||||||
public AjaxResult exportSingle(@PathVariable("id") Integer id) {
|
public AjaxResult exportSingle(@PathVariable("id") Integer id) {
|
||||||
return AjaxResult.success(quotationService.exportSingle(id));
|
return AjaxResult.success(quotationService.exportSingle(id));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,7 @@ public class ProjectInfo extends BaseEntity
|
||||||
|
|
||||||
private List<OmsFileLog> projectFileList;
|
private List<OmsFileLog> projectFileList;
|
||||||
private String fileId;
|
private String fileId;
|
||||||
|
private String partnerSystemUserId;
|
||||||
private Integer quotationId;
|
private Integer quotationId;
|
||||||
private List<Integer> quotationIdList;
|
private List<Integer> quotationIdList;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ public class Quotation extends BaseEntity {
|
||||||
* 项目编号
|
* 项目编号
|
||||||
*/
|
*/
|
||||||
private String projectCode;
|
private String projectCode;
|
||||||
|
private String projectName;
|
||||||
/**
|
/**
|
||||||
* 报价金额
|
* 报价金额
|
||||||
*/
|
*/
|
||||||
|
|
@ -78,6 +79,8 @@ public class Quotation extends BaseEntity {
|
||||||
private List<QuotationProductInfo> hardwareProjectProductInfoList;
|
private List<QuotationProductInfo> hardwareProjectProductInfoList;
|
||||||
// @Excel(name = "服务")
|
// @Excel(name = "服务")
|
||||||
private List<QuotationProductInfo> maintenanceProjectProductInfoList;
|
private List<QuotationProductInfo> maintenanceProjectProductInfoList;
|
||||||
|
//省代
|
||||||
|
private List<QuotationProductInfo> provinceProductInfoList;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public enum QuotationStatusEnum {
|
public enum QuotationStatusEnum {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
|
||||||
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
|
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
|
||||||
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
|
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
|
||||||
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
|
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
|
||||||
|
import com.ruoyi.common.annotation.DataScope;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
import com.ruoyi.common.utils.PageUtils;
|
import com.ruoyi.common.utils.PageUtils;
|
||||||
import com.ruoyi.common.utils.ShiroUtils;
|
import com.ruoyi.common.utils.ShiroUtils;
|
||||||
|
|
@ -69,6 +70,7 @@ public class QuotationServiceImpl implements IQuotationService {
|
||||||
* @return 对象列表
|
* @return 对象列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@DataScope(deptAlias = "u", userAlias = "u")
|
||||||
public List<Quotation> queryAll(Quotation quotation) {
|
public List<Quotation> queryAll(Quotation quotation) {
|
||||||
List<Quotation> dataList = quotationMapper.queryAll(quotation);
|
List<Quotation> dataList = quotationMapper.queryAll(quotation);
|
||||||
PageUtils.clearPage();
|
PageUtils.clearPage();
|
||||||
|
|
@ -95,7 +97,14 @@ public class QuotationServiceImpl implements IQuotationService {
|
||||||
maintenanceProjectProductInfoList.addAll(productListMap.getOrDefault(ProductInfo.ProductTypeEnum.SOFTWARE_MAINTENANCE.getType(), new ArrayList<>()));
|
maintenanceProjectProductInfoList.addAll(productListMap.getOrDefault(ProductInfo.ProductTypeEnum.SOFTWARE_MAINTENANCE.getType(), new ArrayList<>()));
|
||||||
maintenanceProjectProductInfoList.addAll(productListMap.getOrDefault(ProductInfo.ProductTypeEnum.OTHER.getType(), new ArrayList<>()));
|
maintenanceProjectProductInfoList.addAll(productListMap.getOrDefault(ProductInfo.ProductTypeEnum.OTHER.getType(), new ArrayList<>()));
|
||||||
quotation.setMaintenanceProjectProductInfoList(maintenanceProjectProductInfoList);
|
quotation.setMaintenanceProjectProductInfoList(maintenanceProjectProductInfoList);
|
||||||
|
quotation.setProvinceProductInfoList(productListMap.getOrDefault(ProductInfo.ProductTypeEnum.PROVINCE_SERVICE.getType(),new ArrayList<>()));
|
||||||
|
ProjectInfo projectInfo = new ProjectInfo();
|
||||||
|
projectInfo.setQuotationId(quotation.getId());
|
||||||
|
List<ProjectInfo> projectInfos = projectInfoService.selectProjectInfoList(projectInfo);
|
||||||
|
quotation.setProjectCode(projectInfos.stream().map(ProjectInfo::getProjectCode).collect(Collectors.joining(",")));
|
||||||
|
quotation.setProjectName(projectInfos.stream().map(ProjectInfo::getProjectName).collect(Collectors.joining(",")));
|
||||||
}
|
}
|
||||||
|
|
||||||
return quotation;
|
return quotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -187,46 +196,42 @@ public class QuotationServiceImpl implements IQuotationService {
|
||||||
row1.add("");
|
row1.add("");
|
||||||
}
|
}
|
||||||
rows.add(row1);
|
rows.add(row1);
|
||||||
|
rows.add(Collections.emptyList());
|
||||||
|
|
||||||
// Calculate Date
|
// Calculate Date
|
||||||
String validDate = LocalDate.now().plusDays(7).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
String validDate = LocalDate.now().plusDays(7).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||||
|
|
||||||
// Helper to create padded row
|
// Helper to create padded row
|
||||||
List<Object> row2 = new ArrayList<>();
|
List<Object> row2 = new ArrayList<>();
|
||||||
row2.add("项目名称:");
|
row2.add("");
|
||||||
row2.add(quotation.getQuotationName());
|
row2.add("*项目名称:");
|
||||||
|
row2.add(quotation.getProjectName());
|
||||||
row2.add("");
|
row2.add("");
|
||||||
row2.add("");
|
row2.add("");
|
||||||
row2.add("");
|
row2.add("");
|
||||||
row2.add(""); // Padding
|
row2.add("*本报价单有效期至:"+validDate);
|
||||||
row2.add("*本报价单有效期至:");
|
|
||||||
row2.add(validDate);
|
|
||||||
rows.add(row2);
|
rows.add(row2);
|
||||||
|
|
||||||
List<Object> row3 = new ArrayList<>();
|
List<Object> row3 = new ArrayList<>();
|
||||||
|
row3.add("");
|
||||||
row3.add("*项目ID:");
|
row3.add("*项目ID:");
|
||||||
row3.add(quotation.getProjectCode());
|
row3.add(quotation.getProjectCode());
|
||||||
row3.add("");
|
row3.add("(项目名称和ID在商务申请时必填)");
|
||||||
row3.add("");
|
|
||||||
row3.add("");
|
row3.add("");
|
||||||
row3.add("");
|
row3.add("");
|
||||||
row3.add("*云桌面完整报价单必须包含部署服务、现场维保、省代集成服务,此三项由省代进行补充报价,不能缺项");
|
row3.add("*云桌面完整报价单必须包含部署服务、现场维保、省代集成服务,此三项由省代进行补充报价,不能缺项");
|
||||||
rows.add(row3);
|
rows.add(row3);
|
||||||
|
|
||||||
List<Object> row4 = new ArrayList<>();
|
List<Object> row4 = new ArrayList<>();
|
||||||
|
row4.add("");
|
||||||
row4.add("国家/地区 :");
|
row4.add("国家/地区 :");
|
||||||
row4.add("中国大陆");
|
row4.add("中国大陆");
|
||||||
row4.add("");
|
row4.add("");
|
||||||
row4.add("");
|
row4.add("");
|
||||||
row4.add("");
|
row4.add("");
|
||||||
row4.add("");
|
|
||||||
row4.add("*因上游CPU、内存、存储波动较大,封标前3天与汇智区域接口人邮件确定商务折扣和供货周期,否则报价单无效");
|
row4.add("*因上游CPU、内存、存储波动较大,封标前3天与汇智区域接口人邮件确定商务折扣和供货周期,否则报价单无效");
|
||||||
rows.add(row4);
|
rows.add(row4);
|
||||||
|
|
||||||
List<Object> row5 = new ArrayList<>();
|
|
||||||
row5.add("备注:");
|
|
||||||
row5.add(quotation.getRemark());
|
|
||||||
rows.add(row5);
|
|
||||||
|
|
||||||
rows.add(Collections.emptyList());
|
rows.add(Collections.emptyList());
|
||||||
|
|
||||||
|
|
@ -236,18 +241,25 @@ public class QuotationServiceImpl implements IQuotationService {
|
||||||
"目录单价(RMB)", "推荐折扣", "折扣单价(RMB)", "总价(RMB)",
|
"目录单价(RMB)", "推荐折扣", "折扣单价(RMB)", "总价(RMB)",
|
||||||
"目录总价(RMB)", "CID信息", "备注"
|
"目录总价(RMB)", "CID信息", "备注"
|
||||||
);
|
);
|
||||||
// 记录列标题行索引,使其变灰
|
// 记录列标题行索引
|
||||||
|
int headerRowIndex = rows.size();
|
||||||
Set<Integer> coloredRowIndices = new HashSet<>();
|
Set<Integer> coloredRowIndices = new HashSet<>();
|
||||||
coloredRowIndices.add(rows.size());
|
// 标题列填充灰色
|
||||||
|
coloredRowIndices.add(headerRowIndex);
|
||||||
rows.add(new ArrayList<>(headers));
|
rows.add(new ArrayList<>(headers));
|
||||||
|
|
||||||
// 3. 第三部分:数据分组
|
// 3. 第三部分:数据分组
|
||||||
Set<Integer> aquaRowIndices = new HashSet<>();
|
Set<Integer> aquaRowIndices = new HashSet<>();
|
||||||
AtomicInteger sectionCounter = new AtomicInteger(1);
|
AtomicInteger sectionCounter = new AtomicInteger(1);
|
||||||
|
|
||||||
addSection(rows, "软件", quotation.getSoftwareProjectProductInfoList(), coloredRowIndices, aquaRowIndices, sectionCounter);
|
// 添加默认分组:云桌面服务器
|
||||||
addSection(rows, "硬件", quotation.getHardwareProjectProductInfoList(), coloredRowIndices, aquaRowIndices, sectionCounter);
|
QuotationProductInfo defaultItem = new QuotationProductInfo();
|
||||||
addSection(rows, "服务", quotation.getMaintenanceProjectProductInfoList(), coloredRowIndices, aquaRowIndices, sectionCounter);
|
|
||||||
|
addSection(rows, "云桌面服务器","VOI/VDI服务器", Collections.singletonList(defaultItem), coloredRowIndices, aquaRowIndices, sectionCounter);
|
||||||
|
|
||||||
|
addSection(rows, "云桌面软件", "Workspace/learningspace/NEX",quotation.getSoftwareProjectProductInfoList(), coloredRowIndices, aquaRowIndices, sectionCounter);
|
||||||
|
addSection(rows, "云终端", "VOI/VDI终端",quotation.getHardwareProjectProductInfoList(), coloredRowIndices, aquaRowIndices, sectionCounter);
|
||||||
|
addSection(rows, "省代服务(若从省代出货需计算)","省代服务", quotation.getProvinceProductInfoList(), coloredRowIndices, aquaRowIndices, sectionCounter);
|
||||||
|
|
||||||
ExcelUtil<Object> util = new ExcelUtil<>(Object.class);
|
ExcelUtil<Object> util = new ExcelUtil<>(Object.class);
|
||||||
String fileName = util.encodingFilename("报价单_" + quotation.getQuotationCode());
|
String fileName = util.encodingFilename("报价单_" + quotation.getQuotationCode());
|
||||||
|
|
@ -257,15 +269,19 @@ public class QuotationServiceImpl implements IQuotationService {
|
||||||
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
|
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
|
||||||
contentWriteCellStyle.setWrapped(true);
|
contentWriteCellStyle.setWrapped(true);
|
||||||
contentWriteCellStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
|
contentWriteCellStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
|
||||||
|
contentWriteCellStyle.setHorizontalAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment.LEFT);
|
||||||
HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(null, contentWriteCellStyle);
|
HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(null, contentWriteCellStyle);
|
||||||
|
|
||||||
EasyExcel.write(filePath)
|
EasyExcel.write(filePath)
|
||||||
.registerWriteHandler(horizontalCellStyleStrategy)
|
.registerWriteHandler(horizontalCellStyleStrategy)
|
||||||
.registerWriteHandler(new CustomColumnWidthStrategy())
|
.registerWriteHandler(new CustomColumnWidthStrategy(headerRowIndex))
|
||||||
.registerWriteHandler(new com.alibaba.excel.write.handler.CellWriteHandler() {
|
.registerWriteHandler(new com.alibaba.excel.write.handler.CellWriteHandler() {
|
||||||
private org.apache.poi.ss.usermodel.CellStyle coloredStyle;
|
private org.apache.poi.ss.usermodel.CellStyle coloredStyle;
|
||||||
|
private org.apache.poi.ss.usermodel.CellStyle coloredLeftStyle;
|
||||||
private org.apache.poi.ss.usermodel.CellStyle aquaStyle;
|
private org.apache.poi.ss.usermodel.CellStyle aquaStyle;
|
||||||
private org.apache.poi.ss.usermodel.CellStyle centerStyle;
|
private org.apache.poi.ss.usermodel.CellStyle centerStyle;
|
||||||
|
private org.apache.poi.ss.usermodel.CellStyle infoStyle;
|
||||||
|
private org.apache.poi.ss.usermodel.CellStyle redInfoStyle;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeCellCreate(com.alibaba.excel.write.metadata.holder.WriteSheetHolder writeSheetHolder, com.alibaba.excel.write.metadata.holder.WriteTableHolder writeTableHolder, org.apache.poi.ss.usermodel.Row row, com.alibaba.excel.metadata.Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
|
public void beforeCellCreate(com.alibaba.excel.write.metadata.holder.WriteSheetHolder writeSheetHolder, com.alibaba.excel.write.metadata.holder.WriteTableHolder writeTableHolder, org.apache.poi.ss.usermodel.Row row, com.alibaba.excel.metadata.Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
|
||||||
|
|
@ -289,6 +305,8 @@ public class QuotationServiceImpl implements IQuotationService {
|
||||||
centerStyle = workbook.createCellStyle();
|
centerStyle = workbook.createCellStyle();
|
||||||
centerStyle.setAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment.CENTER);
|
centerStyle.setAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment.CENTER);
|
||||||
centerStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
|
centerStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
|
||||||
|
centerStyle.setFillForegroundColor(org.apache.poi.ss.usermodel.IndexedColors.WHITE.getIndex());
|
||||||
|
centerStyle.setFillPattern(org.apache.poi.ss.usermodel.FillPatternType.SOLID_FOREGROUND);
|
||||||
org.apache.poi.ss.usermodel.Font font = workbook.createFont();
|
org.apache.poi.ss.usermodel.Font font = workbook.createFont();
|
||||||
font.setBold(true);
|
font.setBold(true);
|
||||||
font.setFontHeightInPoints((short) 16);
|
font.setFontHeightInPoints((short) 16);
|
||||||
|
|
@ -297,21 +315,75 @@ public class QuotationServiceImpl implements IQuotationService {
|
||||||
cell.setCellStyle(centerStyle);
|
cell.setCellStyle(centerStyle);
|
||||||
// Merge cells for title (0-10, Logo is at 11 usually, but let's merge fewer if needed, or 0-10)
|
// Merge cells for title (0-10, Logo is at 11 usually, but let's merge fewer if needed, or 0-10)
|
||||||
writeSheetHolder.getSheet().addMergedRegionUnsafe(new org.apache.poi.ss.util.CellRangeAddress(0, 0, 0, 10));
|
writeSheetHolder.getSheet().addMergedRegionUnsafe(new org.apache.poi.ss.util.CellRangeAddress(0, 0, 0, 10));
|
||||||
}
|
} else if (cell.getRowIndex() < headerRowIndex) {
|
||||||
|
// Info rows (0 to headerRowIndex-1) - Excluding 0 handled above?
|
||||||
|
// Actually handle 0 separately or here. 0 is handled above.
|
||||||
|
if (cell.getRowIndex() == 0) return;
|
||||||
|
|
||||||
if (coloredRowIndices.contains(cell.getRowIndex())) {
|
// Check for Red Font Conditions
|
||||||
if (coloredStyle == null) {
|
boolean isRed = false;
|
||||||
org.apache.poi.ss.usermodel.Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
|
if (cell.getRowIndex() == 2 && (cell.getColumnIndex() == 3 || cell.getColumnIndex() == 6)) {
|
||||||
coloredStyle = workbook.createCellStyle();
|
isRed = true;
|
||||||
coloredStyle.setFillForegroundColor(org.apache.poi.ss.usermodel.IndexedColors.GREY_25_PERCENT.getIndex());
|
} else if (cell.getRowIndex() == 3 && (cell.getColumnIndex() == 6 || cell.getColumnIndex() == 3)) {
|
||||||
coloredStyle.setFillPattern(org.apache.poi.ss.usermodel.FillPatternType.SOLID_FOREGROUND);
|
isRed = true;
|
||||||
coloredStyle.setWrapText(true);
|
} else if (cell.getRowIndex() == 4 && cell.getColumnIndex() == 6) {
|
||||||
coloredStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
|
isRed = true;
|
||||||
org.apache.poi.ss.usermodel.Font font = workbook.createFont();
|
}
|
||||||
font.setBold(true);
|
|
||||||
coloredStyle.setFont(font);
|
if (isRed) {
|
||||||
|
if (redInfoStyle == null) {
|
||||||
|
org.apache.poi.ss.usermodel.Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
|
||||||
|
redInfoStyle = workbook.createCellStyle();
|
||||||
|
redInfoStyle.setFillForegroundColor(org.apache.poi.ss.usermodel.IndexedColors.WHITE.getIndex());
|
||||||
|
redInfoStyle.setFillPattern(org.apache.poi.ss.usermodel.FillPatternType.SOLID_FOREGROUND);
|
||||||
|
redInfoStyle.setWrapText(false);
|
||||||
|
redInfoStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
|
||||||
|
org.apache.poi.ss.usermodel.Font font = workbook.createFont();
|
||||||
|
font.setColor(org.apache.poi.ss.usermodel.IndexedColors.RED.getIndex());
|
||||||
|
redInfoStyle.setFont(font);
|
||||||
|
}
|
||||||
|
cell.setCellStyle(redInfoStyle);
|
||||||
|
} else {
|
||||||
|
if (infoStyle == null) {
|
||||||
|
org.apache.poi.ss.usermodel.Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
|
||||||
|
infoStyle = workbook.createCellStyle();
|
||||||
|
infoStyle.setFillForegroundColor(org.apache.poi.ss.usermodel.IndexedColors.WHITE.getIndex());
|
||||||
|
infoStyle.setFillPattern(org.apache.poi.ss.usermodel.FillPatternType.SOLID_FOREGROUND);
|
||||||
|
infoStyle.setWrapText(false);
|
||||||
|
infoStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
|
||||||
|
}
|
||||||
|
cell.setCellStyle(infoStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (coloredRowIndices.contains(cell.getRowIndex())) {
|
||||||
|
if (cell.getRowIndex() > headerRowIndex) {
|
||||||
|
if (coloredLeftStyle == null) {
|
||||||
|
org.apache.poi.ss.usermodel.Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
|
||||||
|
coloredLeftStyle = workbook.createCellStyle();
|
||||||
|
coloredLeftStyle.setFillForegroundColor(org.apache.poi.ss.usermodel.IndexedColors.GREY_25_PERCENT.getIndex());
|
||||||
|
coloredLeftStyle.setFillPattern(org.apache.poi.ss.usermodel.FillPatternType.SOLID_FOREGROUND);
|
||||||
|
coloredLeftStyle.setWrapText(true);
|
||||||
|
coloredLeftStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
|
||||||
|
coloredLeftStyle.setAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment.LEFT);
|
||||||
|
org.apache.poi.ss.usermodel.Font font = workbook.createFont();
|
||||||
|
font.setBold(true);
|
||||||
|
coloredLeftStyle.setFont(font);
|
||||||
|
}
|
||||||
|
cell.setCellStyle(coloredLeftStyle);
|
||||||
|
} else {
|
||||||
|
if (coloredStyle == null) {
|
||||||
|
org.apache.poi.ss.usermodel.Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
|
||||||
|
coloredStyle = workbook.createCellStyle();
|
||||||
|
coloredStyle.setFillForegroundColor(org.apache.poi.ss.usermodel.IndexedColors.GREY_25_PERCENT.getIndex());
|
||||||
|
coloredStyle.setFillPattern(org.apache.poi.ss.usermodel.FillPatternType.SOLID_FOREGROUND);
|
||||||
|
coloredStyle.setWrapText(true);
|
||||||
|
coloredStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
|
||||||
|
org.apache.poi.ss.usermodel.Font font = workbook.createFont();
|
||||||
|
font.setBold(true);
|
||||||
|
coloredStyle.setFont(font);
|
||||||
|
}
|
||||||
|
cell.setCellStyle(coloredStyle);
|
||||||
}
|
}
|
||||||
cell.setCellStyle(coloredStyle);
|
|
||||||
} else if (aquaRowIndices.contains(cell.getRowIndex())) {
|
} else if (aquaRowIndices.contains(cell.getRowIndex())) {
|
||||||
if (aquaStyle == null) {
|
if (aquaStyle == null) {
|
||||||
org.apache.poi.ss.usermodel.Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
|
org.apache.poi.ss.usermodel.Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
|
||||||
|
|
@ -319,6 +391,7 @@ public class QuotationServiceImpl implements IQuotationService {
|
||||||
aquaStyle.setFillForegroundColor(org.apache.poi.ss.usermodel.IndexedColors.AQUA.getIndex());
|
aquaStyle.setFillForegroundColor(org.apache.poi.ss.usermodel.IndexedColors.AQUA.getIndex());
|
||||||
aquaStyle.setFillPattern(org.apache.poi.ss.usermodel.FillPatternType.SOLID_FOREGROUND);
|
aquaStyle.setFillPattern(org.apache.poi.ss.usermodel.FillPatternType.SOLID_FOREGROUND);
|
||||||
aquaStyle.setWrapText(true);
|
aquaStyle.setWrapText(true);
|
||||||
|
aquaStyle.setAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment.LEFT);
|
||||||
}
|
}
|
||||||
cell.setCellStyle(aquaStyle);
|
cell.setCellStyle(aquaStyle);
|
||||||
}
|
}
|
||||||
|
|
@ -350,7 +423,7 @@ public class QuotationServiceImpl implements IQuotationService {
|
||||||
quotationMapper.update(quotation);
|
quotationMapper.update(quotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSection(List<List<Object>> rows, String title, List<QuotationProductInfo> list, Set<Integer> coloredRowIndices, Set<Integer> aquaRowIndices, AtomicInteger sectionCounter) {
|
private void addSection(List<List<Object>> rows, String title, String subTitle,List<QuotationProductInfo> list, Set<Integer> coloredRowIndices, Set<Integer> aquaRowIndices, AtomicInteger sectionCounter) {
|
||||||
if (CollUtil.isEmpty(list)) {
|
if (CollUtil.isEmpty(list)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -367,6 +440,18 @@ public class QuotationServiceImpl implements IQuotationService {
|
||||||
}
|
}
|
||||||
rows.add(titleRow);
|
rows.add(titleRow);
|
||||||
|
|
||||||
|
// 添加标题行 (补齐12列)
|
||||||
|
List<Object> subTitleRow = new ArrayList<>();
|
||||||
|
subTitleRow.add(currentSection+"_"+currentSection);
|
||||||
|
subTitleRow.add(subTitle);
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
subTitleRow.add("");
|
||||||
|
}
|
||||||
|
rows.add(subTitleRow);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
double sumAllPrice = 0.0;
|
double sumAllPrice = 0.0;
|
||||||
double sumCatalogueAllPrice = 0.0;
|
double sumCatalogueAllPrice = 0.0;
|
||||||
|
|
||||||
|
|
@ -374,7 +459,7 @@ public class QuotationServiceImpl implements IQuotationService {
|
||||||
int index = 1;
|
int index = 1;
|
||||||
for (QuotationProductInfo item : list) {
|
for (QuotationProductInfo item : list) {
|
||||||
List<Object> row = new ArrayList<>();
|
List<Object> row = new ArrayList<>();
|
||||||
row.add(currentSection + "_" + index++);
|
row.add("");
|
||||||
row.add(item.getProductBomCode());
|
row.add(item.getProductBomCode());
|
||||||
row.add(item.getModel());
|
row.add(item.getModel());
|
||||||
row.add(item.getProductDesc());
|
row.add(item.getProductDesc());
|
||||||
|
|
@ -400,7 +485,7 @@ public class QuotationServiceImpl implements IQuotationService {
|
||||||
coloredRowIndices.add(rows.size());
|
coloredRowIndices.add(rows.size());
|
||||||
List<Object> subTotalRow1 = new ArrayList<>();
|
List<Object> subTotalRow1 = new ArrayList<>();
|
||||||
subTotalRow1.add("");
|
subTotalRow1.add("");
|
||||||
subTotalRow1.add(title);
|
subTotalRow1.add(subTitle);
|
||||||
subTotalRow1.add("");
|
subTotalRow1.add("");
|
||||||
subTotalRow1.add("");
|
subTotalRow1.add("");
|
||||||
subTotalRow1.add("");
|
subTotalRow1.add("");
|
||||||
|
|
@ -434,9 +519,19 @@ public class QuotationServiceImpl implements IQuotationService {
|
||||||
// 自定义列宽策略:自适应但有最大宽度
|
// 自定义列宽策略:自适应但有最大宽度
|
||||||
public static class CustomColumnWidthStrategy extends AbstractColumnWidthStyleStrategy {
|
public static class CustomColumnWidthStrategy extends AbstractColumnWidthStyleStrategy {
|
||||||
private static final int MAX_COLUMN_WIDTH = 50;
|
private static final int MAX_COLUMN_WIDTH = 50;
|
||||||
|
private final int headerRowIndex;
|
||||||
|
|
||||||
|
public CustomColumnWidthStrategy(int headerRowIndex) {
|
||||||
|
this.headerRowIndex = headerRowIndex;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
|
protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
|
||||||
|
// 1-6行不参与列宽计算 (小于标题行的行)
|
||||||
|
if (cell.getRowIndex() < headerRowIndex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isHead != null && isHead) {
|
if (isHead != null && isHead) {
|
||||||
// 如果是表头,不需特别处理,EasyExcel会自动处理,或者这里也可以计算
|
// 如果是表头,不需特别处理,EasyExcel会自动处理,或者这里也可以计算
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -28,70 +28,74 @@
|
||||||
<!--通过实体作为筛选条件查询-->
|
<!--通过实体作为筛选条件查询-->
|
||||||
<select id="queryAll" resultMap="QuotationMap">
|
<select id="queryAll" resultMap="QuotationMap">
|
||||||
select
|
select
|
||||||
<include refid="Base_Column_List"/>
|
t1.id, t1.quotation_code, t1.quotation_name, t1.quotation_amount, t1.discount_amount,
|
||||||
from oms_quotation
|
t1.quotation_status, t1.create_time, t1.create_by, t1.update_by, t1.update_time, t1.remark,
|
||||||
|
t1.agent_code, t1.amount_type, t1.customer_name
|
||||||
|
from oms_quotation t1
|
||||||
|
LEFT join sys_user u on t1.create_by = u.user_id
|
||||||
<where>
|
<where>
|
||||||
<if test="id != null">
|
<if test="id != null">
|
||||||
and id = #{id}
|
and t1.id = #{id}
|
||||||
</if>
|
</if>
|
||||||
<if test="quotationCode != null and quotationCode != ''">
|
<if test="quotationCode != null and quotationCode != ''">
|
||||||
and quotation_code = #{quotationCode}
|
and t1.quotation_code = #{quotationCode}
|
||||||
</if>
|
</if>
|
||||||
<if test="quotationName != null and quotationName != ''">
|
<if test="quotationName != null and quotationName != ''">
|
||||||
and quotation_name = #{quotationName}
|
and t1.quotation_name = #{quotationName}
|
||||||
</if>
|
</if>
|
||||||
|
|
||||||
<if test="quotationAmount != null">
|
<if test="quotationAmount != null">
|
||||||
and quotation_amount = #{quotationAmount}
|
and t1.quotation_amount = #{quotationAmount}
|
||||||
</if>
|
</if>
|
||||||
<if test="discountAmount != null">
|
<if test="discountAmount != null">
|
||||||
and discount_amount = #{discountAmount}
|
and t1.discount_amount = #{discountAmount}
|
||||||
</if>
|
</if>
|
||||||
<if test="quotationStatus != null and quotationStatus != ''">
|
<if test="quotationStatus != null and quotationStatus != ''">
|
||||||
and quotation_status = #{quotationStatus}
|
and t1.quotation_status = #{quotationStatus}
|
||||||
</if>
|
</if>
|
||||||
<if test="createTime != null">
|
<if test="createTime != null">
|
||||||
and create_time = #{createTime}
|
and t1.create_time = #{createTime}
|
||||||
</if>
|
</if>
|
||||||
<if test="createBy != null and createBy != ''">
|
<if test="createBy != null and createBy != ''">
|
||||||
and create_by = #{createBy}
|
and t1.create_by = #{createBy}
|
||||||
</if>
|
</if>
|
||||||
<if test="updateBy != null and updateBy != ''">
|
<if test="updateBy != null and updateBy != ''">
|
||||||
and update_by = #{updateBy}
|
and t1.update_by = #{updateBy}
|
||||||
</if>
|
</if>
|
||||||
<if test="updateTime != null">
|
<if test="updateTime != null">
|
||||||
and update_time = #{updateTime}
|
and t1.update_time = #{updateTime}
|
||||||
</if>
|
</if>
|
||||||
<if test="remark != null and remark != ''">
|
<if test="remark != null and remark != ''">
|
||||||
and remark = #{remark}
|
and t1.remark = #{remark}
|
||||||
</if>
|
</if>
|
||||||
|
|
||||||
<if test="agentCode != null and agentCode != ''">
|
<if test="agentCode != null and agentCode != ''">
|
||||||
and agent_code = #{agentCode}
|
and t1.agent_code = #{agentCode}
|
||||||
</if>
|
</if>
|
||||||
<if test="amountType != null and amountType != ''">
|
<if test="amountType != null and amountType != ''">
|
||||||
and amount_type = #{amountType}
|
and t1.amount_type = #{amountType}
|
||||||
</if>
|
</if>
|
||||||
<if test="customerName != null and customerName != ''">
|
<if test="customerName != null and customerName != ''">
|
||||||
and customer_name = #{customerName}
|
and t1.customer_name = #{customerName}
|
||||||
</if>
|
</if>
|
||||||
<if test="customerName != null and customerName != ''">
|
<if test="customerName != null and customerName != ''">
|
||||||
and customer_name = #{customerName}
|
and t1.customer_name = #{customerName}
|
||||||
</if>
|
</if>
|
||||||
<if test="createTimeStart != null or createTimeEnd != null">
|
<if test="createTimeStart != null or createTimeEnd != null">
|
||||||
<choose>
|
<choose>
|
||||||
<when test="createTimeStart != null and createTimeEnd != null">
|
<when test="createTimeStart != null and createTimeEnd != null">
|
||||||
and create_time between date_format(#{createTimeStart}, '%Y-%m-%d 00:00:00') and date_format(#{createTimeEnd}, '%Y-%m-%d 23:59:59')
|
and t1.create_time between date_format(#{createTimeStart}, '%Y-%m-%d 00:00:00') and date_format(#{createTimeEnd}, '%Y-%m-%d 23:59:59')
|
||||||
</when>
|
</when>
|
||||||
<when test="createTimeStart != null">
|
<when test="createTimeStart != null">
|
||||||
and create_time <![CDATA[ >= ]]> date_format(#{createTimeStart}, '%Y-%m-%d 00:00:00')
|
and t1.create_time <![CDATA[ >= ]]> date_format(#{createTimeStart}, '%Y-%m-%d 00:00:00')
|
||||||
</when>
|
</when>
|
||||||
<when test="createTimeEnd != null">
|
<when test="createTimeEnd != null">
|
||||||
and create_time <![CDATA[ <= ]]> date_format(#{createTimeEnd}, '%Y-%m-%d 23:59:59')
|
and t1.create_time <![CDATA[ <= ]]> date_format(#{createTimeEnd}, '%Y-%m-%d 23:59:59')
|
||||||
</when>
|
</when>
|
||||||
|
|
||||||
</choose>
|
</choose>
|
||||||
</if>
|
</if>
|
||||||
|
${params.dataScope}
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
t3.user_name as hz_support_user_name,
|
t3.user_name as hz_support_user_name,
|
||||||
t5.level,
|
t5.level,
|
||||||
t5.contact_email as partner_email,
|
t5.contact_email as partner_email,
|
||||||
|
t6.system_user_id as partner_system_user_id,
|
||||||
t1.update_time ,
|
t1.update_time ,
|
||||||
ifnull(t4.work_time,t1.update_time) as last_work_update_time
|
ifnull(t4.work_time,t1.update_time) as last_work_update_time
|
||||||
from project_info t1
|
from project_info t1
|
||||||
|
|
@ -98,6 +99,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
left join sys_user t3 on t1.hz_support_user=t3.user_id
|
left join sys_user t3 on t1.hz_support_user=t3.user_id
|
||||||
left join partner_info t5 on t1.partner_code=t5.partner_code
|
left join partner_info t5 on t1.partner_code=t5.partner_code
|
||||||
left join (select max(work_time) work_time,project_id from project_work_progress group by project_id) t4 ON t1.id=t4.project_id
|
left join (select max(work_time) work_time,project_id from project_work_progress group by project_id) t4 ON t1.id=t4.project_id
|
||||||
|
left join partner_info t6 on t1.partner_code=t6.partner_code
|
||||||
|
|
||||||
|
|
||||||
</sql>
|
</sql>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue