Commit 7c52784c authored by huangjie's avatar huangjie

Merge branch 'V20231129-中建一局二公司' of http://192.168.60.201/root/dsk-operate-sys...

Merge branch 'V20231129-中建一局二公司' of http://192.168.60.201/root/dsk-operate-sys into V20231129-中建一局二公司
parents 2a908cf9 afaf8647
...@@ -10,6 +10,7 @@ import com.dsk.cscec.domain.bo.CbSummaryActualListBo; ...@@ -10,6 +10,7 @@ import com.dsk.cscec.domain.bo.CbSummaryActualListBo;
import com.dsk.cscec.domain.bo.CbSummaryActualLockBo; import com.dsk.cscec.domain.bo.CbSummaryActualLockBo;
import com.dsk.cscec.domain.bo.CbSummaryBo; import com.dsk.cscec.domain.bo.CbSummaryBo;
import com.dsk.cscec.domain.vo.CbSummaryActualListVo; import com.dsk.cscec.domain.vo.CbSummaryActualListVo;
import com.dsk.cscec.domain.vo.CbSummaryActualVo;
import com.dsk.cscec.domain.vo.CbSummaryCostAccountExportVo; import com.dsk.cscec.domain.vo.CbSummaryCostAccountExportVo;
import com.dsk.cscec.domain.vo.CbSummaryProjectExportVo; import com.dsk.cscec.domain.vo.CbSummaryProjectExportVo;
import com.dsk.cscec.service.CbSummaryService; import com.dsk.cscec.service.CbSummaryService;
...@@ -58,6 +59,11 @@ public class CbSummaryController extends BaseController { ...@@ -58,6 +59,11 @@ public class CbSummaryController extends BaseController {
return R.ok(cbSummaryService.getActualList(bo)); return R.ok(cbSummaryService.getActualList(bo));
} }
@GetMapping("/allList")
public R<List<CbSummaryActualVo>> getAllList(CbSummaryActualListBo bo) {
return R.ok(cbSummaryService.getAllList(bo));
}
/** /**
* 已添加成本月份 * 已添加成本月份
* *
......
...@@ -13,7 +13,7 @@ import java.util.List; ...@@ -13,7 +13,7 @@ import java.util.List;
* @since 2024-02-06 * @since 2024-02-06
*/ */
@Data @Data
public class CbSummaryActualListVo extends BaseEntity { public class CbSummaryActualListVo {
/** /**
* 主键id * 主键id
*/ */
...@@ -69,19 +69,20 @@ public class CbSummaryActualListVo extends BaseEntity { ...@@ -69,19 +69,20 @@ public class CbSummaryActualListVo extends BaseEntity {
/** /**
* 本月费用(含税) * 本月费用(含税)
*/ */
private BigDecimal taxInclusiveExpense; private Double taxInclusiveExpense;
/** /**
* 本月费用(不含税) * 本月费用(不含税)
*/ */
private BigDecimal taxExclusiveExpense; private Double taxExclusiveExpense;
/** /**
* 截至本月费用(含税) * 截至本月费用(含税)
*/ */
private BigDecimal taxInclusiveExpenseTotal; private Double taxInclusiveExpenseTotal;
/** /**
* 截至本月费用(不含税) * 截至本月费用(不含税)
*/ */
private BigDecimal taxExclusiveExpenseTotal; private Double taxExclusiveExpenseTotal;
/** /**
* 费用日期 * 费用日期
*/ */
......
package com.dsk.cscec.domain.vo;
import lombok.Data;
import java.util.List;
/**
* 成本汇总
*
* @author cyf
* @since 2024-02-06
*/
@Data
public class CbSummaryActualVo {
/**
* 主键id
*/
private Long id;
/**
* 项目id
*/
private Long projectId;
/**
* 成本阶段( 0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
/**
* 层级
*/
private Integer level;
/**
* 序号
*/
private String number;
/**
* 名称/成本科目
*/
private String cbName;
/**
* 不含税成本合价
*/
private String taxExclusiveTotal;
/**
* 成本税金合价
*/
private String cbTaxesTotal;
/**
* 含税成本合价
*/
private String taxInclusiveTotal;
/**
* 成本占比
*/
private String cbProportion;
/**
* 含税成本平米指标
*/
private String taxInclusivePmTarget;
/**
* 备注
*/
private String remark;
/**
* 费用id
*/
private Long actualId;
/**
* 本月费用(含税)
*/
private Double taxInclusiveExpense;
/**
* 本月费用(不含税)
*/
private Double taxExclusiveExpense;
/**
* 截至本月费用(含税)
*/
private Double taxInclusiveExpenseTotal;
/**
* 截至本月费用(不含税)
*/
private Double taxExclusiveExpenseTotal;
/**
* 费用日期
*/
private String expenseDate;
private List<CbSummaryActualVo> children;
}
...@@ -19,5 +19,9 @@ public interface CbCostMeasureActualMapper extends BaseMapper<CbCostMeasureActua ...@@ -19,5 +19,9 @@ public interface CbCostMeasureActualMapper extends BaseMapper<CbCostMeasureActua
List<CbCostMeasureActualVo> getMonthActualCostList(@Param("projectId") Long projectId,@Param("month") String month); List<CbCostMeasureActualVo> getMonthActualCostList(@Param("projectId") Long projectId,@Param("month") String month);
// List<CbCostMeasureActualVo> getMonthActualCostListByLevel(@Param("level") Integer level,@Param("projectId") Long projectId,@Param("month") String month);
BigDecimal selectSumData(CbCostMeasureActualSaveBo bo); BigDecimal selectSumData(CbCostMeasureActualSaveBo bo);
BigDecimal selectMonthProjectVolumeByLevel(@Param("level") Integer level,@Param("projectId") Long projectId,@Param("month") String month);
} }
\ No newline at end of file
...@@ -4,4 +4,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; ...@@ -4,4 +4,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbProjectExpenseSummary; import com.dsk.cscec.domain.CbProjectExpenseSummary;
public interface CbProjectExpenseSummaryMapper extends BaseMapper<CbProjectExpenseSummary> { public interface CbProjectExpenseSummaryMapper extends BaseMapper<CbProjectExpenseSummary> {
} }
\ No newline at end of file
...@@ -8,6 +8,7 @@ import com.dsk.cscec.domain.bo.CbSummaryActualListBo; ...@@ -8,6 +8,7 @@ import com.dsk.cscec.domain.bo.CbSummaryActualListBo;
import com.dsk.cscec.domain.bo.CbSummaryActualLockBo; import com.dsk.cscec.domain.bo.CbSummaryActualLockBo;
import com.dsk.cscec.domain.bo.CbSummaryBo; import com.dsk.cscec.domain.bo.CbSummaryBo;
import com.dsk.cscec.domain.vo.CbSummaryActualListVo; import com.dsk.cscec.domain.vo.CbSummaryActualListVo;
import com.dsk.cscec.domain.vo.CbSummaryActualVo;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -42,7 +43,7 @@ public interface CbSummaryService extends IService<CbSummary> { ...@@ -42,7 +43,7 @@ public interface CbSummaryService extends IService<CbSummary> {
* @return * @return
*/ */
List<CbSummaryActualListVo> getActualList(CbSummaryActualListBo bo); List<CbSummaryActualListVo> getActualList(CbSummaryActualListBo bo);
List<CbSummaryActualVo> getAllList(CbSummaryActualListBo bo);
/** /**
* 获取已添加成本月份 * 获取已添加成本月份
* *
......
...@@ -6,6 +6,7 @@ import com.dsk.cscec.domain.CbCostMeasureActual; ...@@ -6,6 +6,7 @@ import com.dsk.cscec.domain.CbCostMeasureActual;
import com.dsk.cscec.domain.bo.CbCostMeasureActualBo; import com.dsk.cscec.domain.bo.CbCostMeasureActualBo;
import com.dsk.cscec.domain.bo.CbCostMeasureActualSaveBo; import com.dsk.cscec.domain.bo.CbCostMeasureActualSaveBo;
import com.dsk.cscec.domain.vo.CbCostMeasureActualVo; import com.dsk.cscec.domain.vo.CbCostMeasureActualVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.math.BigDecimal; import java.math.BigDecimal;
...@@ -23,5 +24,7 @@ public interface ICbCostMeasureActualService extends IService<CbCostMeasureActua ...@@ -23,5 +24,7 @@ public interface ICbCostMeasureActualService extends IService<CbCostMeasureActua
List<CbCostMeasureActualVo> getMonthActualCostList(Long projectId, String month); List<CbCostMeasureActualVo> getMonthActualCostList(Long projectId, String month);
BigDecimal selectSumData(CbCostMeasureActualSaveBo bo); BigDecimal selectSumData(CbCostMeasureActualSaveBo bo);
BigDecimal selectMonthProjectVolumeByLevel(Integer level, Long projectId, String month);
} }
...@@ -245,6 +245,12 @@ public class CbCostMeasureServiceImpl extends ServiceImpl<CbCostMeasureMapper, C ...@@ -245,6 +245,12 @@ public class CbCostMeasureServiceImpl extends ServiceImpl<CbCostMeasureMapper, C
saveList.add(cbCostMeasureActual); saveList.add(cbCostMeasureActual);
} }
cbCostMeasureActualService.saveOrUpdateBatch(saveList); cbCostMeasureActualService.saveOrUpdateBatch(saveList);
CbCostMeasureActual cbCostMeasureActual = saveList.get(0);
//todo 查询最新的二级费用合计, 用于更新一级费用项
// cbCostMeasureActualService.selectMonthProjectVolumeByLevel(1,cbCostMeasureActual.GET);
//更新
} }
@Override @Override
......
...@@ -19,6 +19,7 @@ import com.dsk.cscec.domain.bo.CbSummaryActualListBo; ...@@ -19,6 +19,7 @@ import com.dsk.cscec.domain.bo.CbSummaryActualListBo;
import com.dsk.cscec.domain.bo.CbSummaryActualLockBo; import com.dsk.cscec.domain.bo.CbSummaryActualLockBo;
import com.dsk.cscec.domain.bo.CbSummaryBo; import com.dsk.cscec.domain.bo.CbSummaryBo;
import com.dsk.cscec.domain.vo.CbSummaryActualListVo; import com.dsk.cscec.domain.vo.CbSummaryActualListVo;
import com.dsk.cscec.domain.vo.CbSummaryActualVo;
import com.dsk.cscec.domain.vo.CbSummaryCostAccountImportVo; import com.dsk.cscec.domain.vo.CbSummaryCostAccountImportVo;
import com.dsk.cscec.domain.vo.CbSummaryProjectImportVo; import com.dsk.cscec.domain.vo.CbSummaryProjectImportVo;
import com.dsk.cscec.listener.CbSummaryCostAccountImportListener; import com.dsk.cscec.listener.CbSummaryCostAccountImportListener;
...@@ -329,18 +330,18 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary ...@@ -329,18 +330,18 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary
if (ObjectUtil.isEmpty(cbSummaryActualListVo)) { if (ObjectUtil.isEmpty(cbSummaryActualListVo)) {
return list; return list;
} }
//截至本月费用汇总 // //截至本月费用汇总
Map<String, BigDecimal> parentTotal = cbSummaryActualMapper.getTotal(cbSummaryActualListVo.getId(), bo.getExpenseDate()); // Map<String, BigDecimal> parentTotal = cbSummaryActualMapper.getTotal(cbSummaryActualListVo.getId(), bo.getExpenseDate());
cbSummaryActualListVo.setTaxExclusiveExpenseTotal(parentTotal.get("taxExclusiveExpenseTotal")); // cbSummaryActualListVo.setTaxExclusiveExpenseTotal(parentTotal.get("taxExclusiveExpenseTotal").doubleValue());
cbSummaryActualListVo.setTaxInclusiveExpenseTotal(parentTotal.get("taxInclusiveExpenseTotal")); // cbSummaryActualListVo.setTaxInclusiveExpenseTotal(parentTotal.get("taxInclusiveExpenseTotal").doubleValue());
List<CbSummaryActualListVo> childrenList = baseMapper.getByParentId(bo.getId(), bo.getExpenseDate()); List<CbSummaryActualListVo> childrenList = baseMapper.getByParentId(bo.getId(), bo.getExpenseDate());
//截至本月费用汇总 // //截至本月费用汇总
childrenList.parallelStream().forEach(children -> { // childrenList.parallelStream().forEach(children -> {
Map<String, BigDecimal> total = cbSummaryActualMapper.getTotal(children.getId(), bo.getExpenseDate()); // Map<String, BigDecimal> total = cbSummaryActualMapper.getTotal(children.getId(), bo.getExpenseDate());
children.setTaxExclusiveExpenseTotal(total.get("taxExclusiveExpenseTotal")); // children.setTaxExclusiveExpenseTotal(total.get("taxExclusiveExpenseTotal").doubleValue());
children.setTaxInclusiveExpenseTotal(total.get("taxInclusiveExpenseTotal")); // children.setTaxInclusiveExpenseTotal(total.get("taxInclusiveExpenseTotal").doubleValue());
}); // });
if (CollectionUtil.isNotEmpty(childrenList)) { if (CollectionUtil.isNotEmpty(childrenList)) {
cbSummaryActualListVo.setHasChildren(1); cbSummaryActualListVo.setHasChildren(1);
} else { } else {
...@@ -375,6 +376,60 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary ...@@ -375,6 +376,60 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary
} }
@Override
public List<CbSummaryActualVo> getAllList(CbSummaryActualListBo bo) {
Assert.notNull(bo.getId(), "id不能为空");
Assert.notNull(bo.getCbType(), "成本类型不能为空");
if (StringUtil.isBlank(bo.getExpenseDate())) {
//默认当前月
bo.setExpenseDate(DatePattern.SIMPLE_MONTH_FORMAT.format(new Date()));
}
List<CbSummaryActualListVo> list = new ArrayList<>();
//当前父级数据
CbSummaryActualListVo cbSummaryActualListVo = baseMapper.getById(bo.getId(), bo.getExpenseDate());
if (ObjectUtil.isEmpty(cbSummaryActualListVo) || null == cbSummaryActualListVo.getId()) {
return new ArrayList<>();
}
// //截至本月费用汇总
// Map<String, BigDecimal> parentTotal = cbSummaryActualMapper.getTotal(cbSummaryActualListVo.getId(), bo.getExpenseDate());
// cbSummaryActualListVo.setTaxExclusiveExpenseTotal(parentTotal.get("taxExclusiveExpenseTotal").doubleValue());
// cbSummaryActualListVo.setTaxInclusiveExpenseTotal(parentTotal.get("taxInclusiveExpenseTotal").doubleValue());
List<CbSummaryActualListVo> childrenList = baseMapper.getByParentId(bo.getId(), bo.getExpenseDate());
// //截至本月费用汇总
// childrenList.parallelStream().forEach(children -> {
// Map<String, BigDecimal> total = cbSummaryActualMapper.getTotal(children.getId(), bo.getExpenseDate());
// children.setTaxExclusiveExpenseTotal(total.get("taxExclusiveExpenseTotal").doubleValue());
// children.setTaxInclusiveExpenseTotal(total.get("taxInclusiveExpenseTotal").doubleValue());
// });
// if (CollectionUtil.isNotEmpty(childrenList)) {
// cbSummaryActualListVo.setHasChildren(1);
// } else {
// cbSummaryActualListVo.setHasChildren(0);
// }
if (0 == cbSummaryActualListVo.getLevel() && 1 == bo.getCbType()) {
//项目汇总一级列表
list = childrenList;
// return childrenList;
} else if (0 == cbSummaryActualListVo.getLevel() && 2 == bo.getCbType()) {
//成本科目汇总一级列表
cbSummaryActualListVo.setChildren(childrenList);
list.add(cbSummaryActualListVo);
// return list;
} else {
//递归列表
childrenList = getProjectSumList(bo);
cbSummaryActualListVo.setChildren(childrenList);
list.add(cbSummaryActualListVo);
// return list;
}
List<CbSummaryActualVo> resultList = BeanUtil.copyToList(list,CbSummaryActualVo.class);
return resultList;
}
/** /**
* 成本汇总递归列表 * 成本汇总递归列表
* *
...@@ -389,10 +444,10 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary ...@@ -389,10 +444,10 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary
childBo.setId(children.getId()); childBo.setId(children.getId());
childBo.setExpenseDate(bo.getExpenseDate()); childBo.setExpenseDate(bo.getExpenseDate());
children.setChildren(getProjectSumList(childBo)); children.setChildren(getProjectSumList(childBo));
//截至本月费用汇总 // //截至本月费用汇总
Map<String, BigDecimal> total = cbSummaryActualMapper.getTotal(children.getId(), bo.getExpenseDate()); // Map<String, BigDecimal> total = cbSummaryActualMapper.getTotal(children.getId(), bo.getExpenseDate());
children.setTaxExclusiveExpenseTotal(total.get("taxExclusiveExpenseTotal")); // children.setTaxExclusiveExpenseTotal(total.get("taxExclusiveExpenseTotal").doubleValue());
children.setTaxInclusiveExpenseTotal(total.get("taxInclusiveExpenseTotal")); // children.setTaxInclusiveExpenseTotal(total.get("taxInclusiveExpenseTotal").doubleValue());
}); });
return childrenList; return childrenList;
...@@ -533,8 +588,8 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary ...@@ -533,8 +588,8 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary
//截至本月费用汇总 //截至本月费用汇总
resultList.forEach(cbSummaryActualListVo -> { resultList.forEach(cbSummaryActualListVo -> {
Map<String, BigDecimal> total = cbSummaryActualMapper.getTotal(cbSummaryActualListVo.getId(), bo.getExpenseDate()); Map<String, BigDecimal> total = cbSummaryActualMapper.getTotal(cbSummaryActualListVo.getId(), bo.getExpenseDate());
cbSummaryActualListVo.setTaxExclusiveExpenseTotal(total.get("taxExclusiveExpenseTotal")); cbSummaryActualListVo.setTaxExclusiveExpenseTotal(total.get("taxExclusiveExpenseTotal").doubleValue());
cbSummaryActualListVo.setTaxInclusiveExpenseTotal(total.get("taxInclusiveExpenseTotal")); cbSummaryActualListVo.setTaxInclusiveExpenseTotal(total.get("taxInclusiveExpenseTotal").doubleValue());
}); });
return resultList; return resultList;
} }
......
...@@ -29,4 +29,9 @@ public class ICbCostMeasureActualServiceImpl extends ServiceImpl<CbCostMeasureAc ...@@ -29,4 +29,9 @@ public class ICbCostMeasureActualServiceImpl extends ServiceImpl<CbCostMeasureAc
public BigDecimal selectSumData(CbCostMeasureActualSaveBo bo) { public BigDecimal selectSumData(CbCostMeasureActualSaveBo bo) {
return baseMapper.selectSumData(bo); return baseMapper.selectSumData(bo);
} }
@Override
public BigDecimal selectMonthProjectVolumeByLevel(Integer level, Long projectId, String month) {
return baseMapper.selectMonthProjectVolumeByLevel(level,projectId,month);
}
} }
...@@ -177,7 +177,7 @@ ...@@ -177,7 +177,7 @@
</select> </select>
<select id="getMonthActualCostList" resultType="com.dsk.cscec.domain.vo.CbCostMeasureActualVo"> <select id="getMonthActualCostList" resultType="com.dsk.cscec.domain.vo.CbCostMeasureActualVo">
SELECT t1.item_content, t.cost_effective SELECT t1.item_content, t.project_volume
FROM cb_cost_measure_actual t FROM cb_cost_measure_actual t
inner JOIN cb_cost_measure t1 ON t1.id=t.plan_measure_id inner JOIN cb_cost_measure t1 ON t1.id=t.plan_measure_id
WHERE WHERE
...@@ -190,4 +190,14 @@ ...@@ -190,4 +190,14 @@
SELECT SUM(t.project_volume) measureTotal FROM cb_cost_measure_actual t WHERE t.plan_measure_id=#{planMeasureId} SELECT SUM(t.project_volume) measureTotal FROM cb_cost_measure_actual t WHERE t.plan_measure_id=#{planMeasureId}
and t.month &lt;#{month} and t.month &lt;#{month}
</select> </select>
<select id="selectMonthProjectVolumeByLevel" resultType="java.math.BigDecimal">
SELECT SUM(t.project_volume)
FROM cb_cost_measure_actual t
inner JOIN cb_cost_measure t1 ON t1.id=t.plan_measure_id
WHERE
t1.project_id=#{projectId}
AND t1.level=#{level}
AND t.`month`=#{month}
</select>
</mapper> </mapper>
\ No newline at end of file
...@@ -30,20 +30,25 @@ ...@@ -30,20 +30,25 @@
</sql> </sql>
<select id="getByParentId" resultType="com.dsk.cscec.domain.vo.CbSummaryActualListVo"> <select id="getByParentId" resultType="com.dsk.cscec.domain.vo.CbSummaryActualListVo">
select csu.*,csa.id actualId,csa.tax_inclusive_expense,csa.tax_exclusive_expense,csa.expense_date select csu.*,csa.id actualId,csa.tax_inclusive_expense,csa.tax_exclusive_expense,csa.expense_date,
ifnull(sum(csa1.tax_inclusive_expense),0) taxInclusiveExpenseTotal,ifnull(sum(csa1.tax_exclusive_expense),0) taxExclusiveExpenseTotal
from cb_summary csu from cb_summary csu
left join cb_summary_actual csa on csu.id = csa.cb_summary_id and csa.expense_date = #{expenseDate} AND csa.del_flag = 0 left join cb_summary_actual csa on csu.id = csa.cb_summary_id and csa.expense_date = #{expenseDate} AND csa.del_flag = 0
left join cb_summary_actual csa1 on csu.id = csa1.cb_summary_id and csa1.expense_date &lt;= #{expenseDate} AND csa.del_flag = 0
<where> <where>
csu.parent_id = #{parentId} csu.parent_id = #{parentId}
and csu.del_flag = 0 and csu.del_flag = 0
</where> </where>
group by csu.id
order by csu.sort order by csu.sort
</select> </select>
<select id="getById" resultType="com.dsk.cscec.domain.vo.CbSummaryActualListVo"> <select id="getById" resultType="com.dsk.cscec.domain.vo.CbSummaryActualListVo">
select csu.*,csa.id actualId,csa.tax_inclusive_expense,csa.tax_exclusive_expense,csa.expense_date select csu.*,csa.id actualId,csa.tax_inclusive_expense,csa.tax_exclusive_expense,csa.expense_date,
ifnull(sum(csa1.tax_inclusive_expense),0) taxInclusiveExpenseTotal,ifnull(sum(csa1.tax_exclusive_expense),0) taxExclusiveExpenseTotal
from cb_summary csu from cb_summary csu
left join cb_summary_actual csa on csu.id = csa.cb_summary_id and csa.expense_date = #{expenseDate} AND csa.del_flag = 0 left join cb_summary_actual csa on csu.id = csa.cb_summary_id and csa.expense_date = #{expenseDate} AND csa.del_flag = 0
left join cb_summary_actual csa1 on csu.id = csa1.cb_summary_id and csa1.expense_date &lt;= #{expenseDate} AND csa.del_flag = 0
<where> <where>
csu.id = #{id} csu.id = #{id}
and csu.del_flag = 0 and csu.del_flag = 0
......
...@@ -16,7 +16,7 @@ export function checkProjectCodeExist(data) { ...@@ -16,7 +16,7 @@ export function checkProjectCodeExist(data) {
return request({ return request({
url: '/cbProjectRecord/checkProjectCodeExist', url: '/cbProjectRecord/checkProjectCodeExist',
method: 'get', method: 'get',
params:data, params: data,
}); });
} }
//新增项目 //新增项目
...@@ -404,7 +404,7 @@ export const getCostSummaryMonthListApi = (params = {}) => request({ ...@@ -404,7 +404,7 @@ export const getCostSummaryMonthListApi = (params = {}) => request({
}); });
/** /**
* 获取成本汇总数据列表 * 获取成本汇总数据列表 懒加载
* @param {*} params * @param {*} params
* @returns * @returns
*/ */
...@@ -414,3 +414,70 @@ export const getCostSummaryListApi = (params = {}) => request({ ...@@ -414,3 +414,70 @@ export const getCostSummaryListApi = (params = {}) => request({
params params
}); });
/**
* 获取全量成本汇总列表
* @param {*} params
* @returns
*/
export const getCostSummaryAllListApi = (params = {}) => request({
url: "/cbSummary/allList",
method: "get",
params
});
/**
* 锁定成本前提示未填项
* @param {*} params
* @returns
*/
export const validateBeforeCostLockApi = (params = {}) => request({
url: "/cbSummary/getUnfilled",
method: "get",
params
});
/**
* 确定锁定成本
* @param {*} data
* @returns
*/
export const setCostLockApi = (data = {}) => request({
url: "/cbSummary/lockActual",
method: "post",
data
});
/**
* 获取已经锁定成本月份
* @param {*} params
* @returns
*/
export const getLockMonthListApi = (params = {}) => request({
url: "/cbSummary/expenseDateList/locked",
method: "get",
params
});
/**
* 成本汇总导出
* @param {*} data
* @returns
*/
export const exportCostLockExcelApi = (data = {}) => request({
url: "/cbSummary/export",
method: "post",
data,
isFile: true,
responseType: "blob"
});
/**
* 编辑成本 保存成本
* @param {*} data
* @returns
*/
export const saveCostModifyApi = (data = {}) => request({
url: "/cbSummary/editActual",
method: "put",
data
});
...@@ -6,13 +6,13 @@ import Decimal from "decimal.js"; ...@@ -6,13 +6,13 @@ import Decimal from "decimal.js";
* @param {*} num2 * @param {*} num2
* @returns * @returns
*/ */
export const add = (num1, num2, digit = 9, omit = false) => { export const add = (num1, num2, digit = 9, intLen = 20, omit = false) => {
const flag = (!parseFloat(num1) && parseFloat(num1) != "0") || (!parseFloat(num2) && parseFloat(num2) != "0"); const flag = (!parseFloat(num1) && parseFloat(num1) != "0") || (!parseFloat(num2) && parseFloat(num2) != "0");
if (flag) throw new Error("传入参数错误,参数不为number"); if (flag) throw new Error("传入参数错误,参数不为number");
const decimal1 = new Decimal(num1); const decimal1 = new Decimal(num1);
const decimal2 = new Decimal(num2); const decimal2 = new Decimal(num2);
const result = decimal1.plus(decimal2); const result = decimal1.plus(decimal2);
return omit ? result.toFixed(digit, Decimal.ROUND_UP) : result.toDecimalPlaces(digit, Decimal.ROUND_UP).toString(); return omit ? result.toFixed(digit, Decimal.ROUND_UP) : result.toDecimalPlaces(digit, Decimal.ROUND_UP).toSignificantDigits(intLen).toString();
}; };
/** /**
...@@ -21,13 +21,13 @@ export const add = (num1, num2, digit = 9, omit = false) => { ...@@ -21,13 +21,13 @@ export const add = (num1, num2, digit = 9, omit = false) => {
* @param {*} num2 * @param {*} num2
* @returns * @returns
*/ */
export const subtract = (num1, num2, digit = 9, omit = false) => { export const subtract = (num1, num2, digit = 9, intLen = 20, omit = false) => {
const flag = (!parseFloat(num1) && parseFloat(num1) != "0") || (!parseFloat(num2) && parseFloat(num2) != "0"); const flag = (!parseFloat(num1) && parseFloat(num1) != "0") || (!parseFloat(num2) && parseFloat(num2) != "0");
if (flag) throw new Error("传入参数错误,参数不为number"); if (flag) throw new Error("传入参数错误,参数不为number");
const decimal1 = new Decimal(num1); const decimal1 = new Decimal(num1);
const decimal2 = new Decimal(num2); const decimal2 = new Decimal(num2);
const result = decimal1.minus(decimal2); const result = decimal1.minus(decimal2);
return omit ? result.toFixed(digit, Decimal.ROUND_UP) : result.toDecimalPlaces(digit, Decimal.ROUND_UP).toString(); return omit ? result.toFixed(digit, Decimal.ROUND_UP) : result.toDecimalPlaces(digit, Decimal.ROUND_UP).toSignificantDigits(intLen).toString();
}; };
/** /**
...@@ -36,13 +36,13 @@ export const subtract = (num1, num2, digit = 9, omit = false) => { ...@@ -36,13 +36,13 @@ export const subtract = (num1, num2, digit = 9, omit = false) => {
* @param {*} num2 * @param {*} num2
* @returns * @returns
*/ */
export const multiply = (num1, num2, digit = 9, omit = false) => { export const multiply = (num1, num2, digit = 9, intLen = 20, omit = false) => {
const flag = (!parseFloat(num1) && parseFloat(num1) != "0") || (!parseFloat(num2) && parseFloat(num2) != "0"); const flag = (!parseFloat(num1) && parseFloat(num1) != "0") || (!parseFloat(num2) && parseFloat(num2) != "0");
if (flag) throw new Error("传入参数错误,参数不为number"); if (flag) throw new Error("传入参数错误,参数不为number");
const decimal1 = new Decimal(num1); const decimal1 = new Decimal(num1);
const decimal2 = new Decimal(num2); const decimal2 = new Decimal(num2);
const result = decimal1.times(decimal2); const result = decimal1.times(decimal2);
return omit ? result.toFixed(digit, Decimal.ROUND_UP) : result.toDecimalPlaces(digit, Decimal.ROUND_UP).toString(); return omit ? result.toFixed(digit, Decimal.ROUND_UP) : result.toDecimalPlaces(digit, Decimal.ROUND_UP).toSignificantDigits(intLen).toString();
}; };
/** /**
...@@ -51,13 +51,13 @@ export const multiply = (num1, num2, digit = 9, omit = false) => { ...@@ -51,13 +51,13 @@ export const multiply = (num1, num2, digit = 9, omit = false) => {
* @param {*} num2 * @param {*} num2
* @returns * @returns
*/ */
export const divide = (num1, num2, digit = 9, omit = false) => { export const divide = (num1, num2, digit = 9, intLen = 20, omit = false) => {
const flag = (!parseFloat(num1) && parseFloat(num1) != "0") || (!parseFloat(num2) && parseFloat(num2) != "0"); const flag = (!parseFloat(num1) && parseFloat(num1) != "0") || (!parseFloat(num2) && parseFloat(num2) != "0");
if (flag) throw new Error("传入参数错误,参数不为number"); if (flag) throw new Error("传入参数错误,参数不为number");
const decimal1 = new Decimal(num1); const decimal1 = new Decimal(num1);
const decimal2 = new Decimal(num2); const decimal2 = new Decimal(num2);
const result = decimal1.dividedBy(decimal2); const result = decimal1.dividedBy(decimal2);
return omit ? result.toFixed(digit, Decimal.ROUND_UP) : result.toDecimalPlaces(digit, Decimal.ROUND_UP).toString(); return omit ? result.toFixed(digit, Decimal.ROUND_UP) : result.toDecimalPlaces(digit, Decimal.ROUND_UP).toSignificantDigits(intLen).toString();
}; };
// 检测结果是否是负数 // 检测结果是否是负数
......
import axios from 'axios' import axios from 'axios';
import { Notification, MessageBox, Message, Loading } from 'element-ui' import { Notification, MessageBox, Message, Loading } from 'element-ui';
import store from '@/store' import store from '@/store';
import { getToken,getTenantid } from '@/utils/auth' import { getToken, getTenantid } from '@/utils/auth';
import errorCode from '@/utils/errorCode' import errorCode from '@/utils/errorCode';
import { tansParams, blobValidate } from "@/utils/ruoyi"; import { tansParams, blobValidate } from "@/utils/ruoyi";
import cache from '@/plugins/cache' import cache from '@/plugins/cache';
import { saveAs } from 'file-saver' import { saveAs } from 'file-saver';
let downloadLoadingInstance; let downloadLoadingInstance;
// 是否显示重新登录 // 是否显示重新登录
export let isRelogin = { show: false }; export let isRelogin = { show: false };
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';
// 创建axios实例 // 创建axios实例
const service = axios.create({ const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分 // axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API, baseURL: process.env.VUE_APP_BASE_API,
// 超时 // 超时
timeout: 20000 timeout: 20000
}) });
// request拦截器 // request拦截器
service.interceptors.request.use(config => { service.interceptors.request.use(config => {
// 是否需要设置 token // 是否需要设置 token
const isToken = (config.headers || {}).isToken === false const isToken = (config.headers || {}).isToken === false;
// 是否需要防止数据重复提交 // 是否需要防止数据重复提交
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
if (getToken() && !isToken) { if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 config.headers['Authorization'] = 'Bearer ' + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
config.headers['tenantid'] = getTenantid() //携带租户id config.headers['tenantid'] = getTenantid(); //携带租户id
} }
// get请求映射params参数 // get请求映射params参数
if (config.method === 'get' && config.params) { if (config.method === 'get' && config.params) {
...@@ -64,42 +64,50 @@ service.interceptors.request.use(config => { ...@@ -64,42 +64,50 @@ service.interceptors.request.use(config => {
// } // }
// } // }
// } // }
return config return config;
}, error => { }, error => {
console.log(error) console.log(error);
if(error.message.indexOf('timeout')<0 ){ //超时报错不提示 if (error.message.indexOf('timeout') < 0) { //超时报错不提示
Promise.reject(error) Promise.reject(error);
} }
}) });
//频繁发送请求时,返回慢的数据覆盖了返回快的数据 //频繁发送请求时,返回慢的数据覆盖了返回快的数据
let pending = [] let pending = [];
let CancelToken = axios.CancelToken let CancelToken = axios.CancelToken;
let cancelPending = (config) => { let cancelPending = (config) => {
pending.forEach((item, index) => { pending.forEach((item, index) => {
if (config) { if (config) {
// if (item.UrlPath === '/combine/info/memberList' || item.UrlPath === '/combine/info/businessList' || item.UrlPath === '/combine/info/bidPage') { // if (item.UrlPath === '/combine/info/memberList' || item.UrlPath === '/combine/info/businessList' || item.UrlPath === '/combine/info/bidPage') {
if (item.UrlPath === config.url && ['/combine/info/memberList','/combine/info/businessList','/combine/info/bidPage'].includes(config.url)) { if (item.UrlPath === config.url && ['/combine/info/memberList', '/combine/info/businessList', '/combine/info/bidPage'].includes(config.url)) {
item.Cancel() // 取消请求 item.Cancel(); // 取消请求
pending.splice(index, 1) // 移除当前请求记录 pending.splice(index, 1); // 移除当前请求记录
}; };
} else { } else {
item.Cancel() // 取消请求 item.Cancel(); // 取消请求
pending.splice(index, 1) // 移除当前请求记录 pending.splice(index, 1); // 移除当前请求记录
} }
}) });
} };
// 响应拦截器 // 响应拦截器
service.interceptors.response.use(res => { service.interceptors.response.use(res => {
const apiList = ['/login', '/system/user/profile/updatePwd'] //需要提示错误的接口 const { config, headers } = res;
const apiList = ['/login', '/system/user/profile/updatePwd']; //需要提示错误的接口
// 未设置状态码则默认成功状态 // 未设置状态码则默认成功状态
const code = res.data.code || 200; const code = res.data.code || 200;
// 获取错误信息 // 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default'] const msg = errorCode[code] || res.data.msg || errorCode['default'];
// 文件下载
if (config.isFile) {
return {
data: res.data,
fileName: headers["content-disposition"]
};
}
// 二进制数据则直接返回 // 二进制数据则直接返回
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
return res.data return res.data;
} }
if (code === 401) { if (code === 401) {
if (!isRelogin.show) { if (!isRelogin.show) {
...@@ -107,30 +115,30 @@ service.interceptors.response.use(res => { ...@@ -107,30 +115,30 @@ service.interceptors.response.use(res => {
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
isRelogin.show = false; isRelogin.show = false;
store.dispatch('LogOut').then(() => { store.dispatch('LogOut').then(() => {
sessionStorage.removeItem('views') sessionStorage.removeItem('views');
location.href = '/index/gys'; location.href = '/index/gys';
}) });
}).catch(() => { }).catch(() => {
isRelogin.show = false; isRelogin.show = false;
}); });
} }
return Promise.reject('无效的会话,或者会话已过期,请重新登录。') return Promise.reject('无效的会话,或者会话已过期,请重新登录。');
} else if (code === 500) { } else if (code === 500) {
Message({ message: msg, type: 'error' }) Message({ message: msg, type: 'error' });
return Promise.reject(new Error(msg)) return Promise.reject(new Error(msg));
} else if (code === 601) { } else if (code === 601) {
Message({ message: msg, type: 'warning' }) Message({ message: msg, type: 'warning' });
return Promise.reject('error') return Promise.reject('error');
} else if (code !== 200) { } else if (code !== 200) {
Notification.error({ title: msg }) Notification.error({ title: msg });
return Promise.reject('error') return Promise.reject('error');
} else { } else {
// cancelPending(res.config) // cancelPending(res.config)
return res.data return res.data;
} }
},error => { }, error => {
console.log(error); console.log(error);
console.log('err' + error) console.log('err' + error);
let { message } = error; let { message } = error;
/*if (message == "Network Error") { /*if (message == "Network Error") {
message = "后端接口连接异常"; message = "后端接口连接异常";
...@@ -139,44 +147,44 @@ service.interceptors.response.use(res => { ...@@ -139,44 +147,44 @@ service.interceptors.response.use(res => {
} else if (message.includes("Request failed with status code")) { } else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常"; message = "系统接口" + message.substr(message.length - 3) + "异常";
}*/ }*/
if(message=='数据正在处理,请勿重复提交'){ //重复提交,提示样式特殊处理 if (message == '数据正在处理,请勿重复提交') { //重复提交,提示样式特殊处理
Message({ message: message, type: 'warning', duration: 5 * 1000 }) Message({ message: message, type: 'warning', duration: 5 * 1000 });
}else{ } else {
// Message({ message: message, type: 'error', duration: 5 * 1000 }) // Message({ message: message, type: 'error', duration: 5 * 1000 })
} }
if(error.message.indexOf('timeout')<0 ){ //超时报错不提示 if (error.message.indexOf('timeout') < 0) { //超时报错不提示
return Promise.reject(error) return Promise.reject(error);
} }
// return Promise.reject(error) // return Promise.reject(error)
} }
) );
// 通用下载方法 // 通用下载方法
export function download(url, params, filename, config) { export function download(url, params, filename, config) {
downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }) downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", });
return service.post(url, params, { return service.post(url, params, {
transformRequest: [(params) => { return tansParams(params) }], transformRequest: [(params) => { return tansParams(params); }],
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
responseType: 'blob', responseType: 'blob',
...config ...config
}).then(async (data) => { }).then(async (data) => {
const isBlob = blobValidate(data); const isBlob = blobValidate(data);
if (isBlob) { if (isBlob) {
const blob = new Blob([data]) const blob = new Blob([data]);
saveAs(blob, filename) saveAs(blob, filename);
} else { } else {
const resText = await data.text(); const resText = await data.text();
const rspObj = JSON.parse(resText); const rspObj = JSON.parse(resText);
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'];
Message.error(errMsg); Message.error(errMsg);
} }
downloadLoadingInstance.close(); downloadLoadingInstance.close();
}).catch((r) => { }).catch((r) => {
console.error(r) console.error(r);
Message.error('下载文件出现错误,请联系管理员!') Message.error('下载文件出现错误,请联系管理员!');
downloadLoadingInstance.close(); downloadLoadingInstance.close();
}) });
} }
export default service export default service;
<template>
<el-dialog title="填写实际成本" :visible="comDialogStatus" class="cost-month-select-container" @close="dialogClose" :destroy-on-close="true"
:close-on-click-modal="false">
<div class=" dialog-content-inner">
<!-- 成本年份 -->
<div class="cost-year-container">
<span>成本年份</span>
<el-date-picker v-model="time" type="month" placeholder="请选择所需要添加的成本月份" format="yyyy年MM月" value-format="yyyy-MM" class="project-record-date"
@change="timeChange" :picker-options="pickerOptions"></el-date-picker>
</div>
</div>
<!-- 底部按钮 -->
<div class="dialog-content-footer">
<div class="cancel-or-ok">
<el-button size="medium" @click="cancel" class="cancel-select-year">取消</el-button>
<el-button type="primary" size="medium" @click="ok" class="ok-select-year">确定</el-button>
</div>
</div>
</el-dialog>
</template>
<script>
import dayjs from "dayjs";
export default {
name: "costMonthSelect",
props: {
dialogStatus: {
type: Boolean,
default: false
},
projectCreateTime: {
type: String,
default: ""
},
disableMonths: {
type: Array,
default: () => []
}
},
model: {
prop: "dialogStatus",
event: "dialogStatusChange"
},
watch: {
dialogStatus(newValue) {
this.comDialogStatus = newValue;
}
},
data() {
return {
comDialogStatus: this.dialogStatus,
time: "",
pickerOptions: {
disabledDate: this.disabledDateHandler
}
};
},
//可访问data属性
created() {
},
//计算集
computed: {
},
//方法集
methods: {
// 时间选择变化
timeChange(time) {
// console.log(time);
},
cancel() {
this.comDialogStatus = false;
},
ok() {
if (!this.time) {
return this.$message.error("请选择成本年份");
}
// 发布事件
this.$emit("timeSelect", dayjs(this.time).format("YYYYMM"));
this.comDialogStatus = false;
},
reset() {
this.time = "";
},
dialogClose() {
this.$emit("dialogStatusChange", false);
this.reset();
},
disabledDateHandler(optionTime) {
// 选项年月
const _optionTime = dayjs(optionTime).format("YYYYMM");
// 当前项目年月
const _thresholdTime = dayjs(this.projectCreateTime).format("YYYYMM");
// 当前项目年
const _thresholdYear = _thresholdTime.slice(0, 4);
// 当前项目月份 补0
const _thresholdMonth = _thresholdTime.slice(4);
// 是否小于当前项目年月 或 大于 当前项目年月 往后推五年 以及成本月份被锁定 禁用
const lastYearMonth = parseInt(`${parseInt(_thresholdYear) + 5}${_thresholdMonth}`);
if (parseInt(_optionTime) < parseInt(_thresholdTime) || parseInt(_optionTime) > lastYearMonth || this.disableMonths.includes(_optionTime)) {
return true;
}
return false;
}
},
}
</script>
<style lang="scss" scoped>
.cost-month-select-container {
::v-deep .el-dialog {
margin-top: 0px !important;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border-radius: 4px;
width: 480px;
.el-dialog__header {
height: 56px;
padding: 0px 20px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #eeeeee;
box-sizing: border-box;
.el-dialog__title {
font-size: 16px;
font-weight: bold;
color: #232323;
}
.el-dialog__headerbtn {
position: static;
width: 16px;
height: 16px;
.el-dialog__close {
font-size: 16px;
}
}
}
.el-dialog__body {
padding: 0px;
box-sizing: border-box;
.dialog-content-inner {
min-height: 120px;
padding: 24px 20px;
}
.cost-year-container {
display: flex;
align-items: center;
& > span {
color: rgba(35, 35, 35, 0.8);
font-size: 14px;
margin-right: 16px;
white-space: nowrap;
}
.project-record-date {
width: 100%;
.el-input__inner {
height: 30px;
line-height: 30px;
padding: 0px 12px;
border-radius: 2px;
border-color: #dcdfe6;
font-size: 14px;
color: #232323;
font-weight: 350;
}
.el-input__suffix {
right: 12px;
.el-input__icon {
line-height: 30px;
width: auto;
}
}
.el-input__prefix {
display: none;
}
}
}
.dialog-content-footer {
height: 64px;
padding: 0px 20px;
display: flex;
justify-content: flex-end;
align-items: center;
border-top: 1px solid #eeeeee;
box-sizing: border-box;
.cancel-or-ok {
display: flex;
height: 100%;
align-items: center;
.el-button {
padding: 0px 16px;
display: flex;
align-items: center;
justify-content: center;
height: 32px;
font-size: 14px;
&.cancel-select-year {
color: rgba(35, 35, 35, 0.8);
border: 1px solid #dcdfe6;
background: #fff;
}
&.ok-select-year {
background: #0081ff;
border-color: #0081ff;
}
}
}
}
}
}
}
</style>
<template>
<el-dialog title="提示" width="480px" :visible="comLockCostTipDialog" :close-on-click-modal="false" class="lock-cost-tip-container"
@close="dialogClose" :destroy-on-close="true">
<div class="lock-cost-tip-content">{{tipContent}}</div>
<!-- 底部按钮 -->
<div class="lock-cost-tip-footer">
<div class="cancel-btn" @click="cancel">取消</div>
<div class="ok-btn" @click="ok">确定锁定</div>
</div>
</el-dialog>
</template>
<script>
export default {
name: "lockCostTip",
model: {
prop: "lockCostTipDialog",
event: "update:lockCostTipDialog"
},
props: {
lockCostTipDialog: {
type: Boolean,
default: false
},
tipContent: {
type: String,
default: ""
}
},
watch: {
lockCostTipDialog: {
handler(newValue) {
this.comLockCostTipDialog = newValue;
}
}
},
data() {
return {
comLockCostTipDialog: this.lockCostTipDialog
};
},
//可访问data属性
created() {
},
//计算集
computed: {
},
//方法集
methods: {
dialogClose() {
this.$emit("update:lockCostTipDialog", false);
},
cancel() {
this.comLockCostTipDialog = false;
},
ok() {
this.$emit("ok");
}
},
}
</script>
<style lang="scss" scoped>
.lock-cost-tip-container {
::v-deep .el-dialog {
min-height: 240px;
margin-top: 0px !important;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border-radius: 4px;
.el-dialog__header {
padding: 0px 20px;
height: 56px;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #eeeeee;
.el-dialog__title {
color: #232323;
font-size: 16px;
font-weight: bold;
}
.el-dialog__headerbtn {
position: static;
width: 16px;
height: 16px;
}
}
.el-dialog__body {
padding: 0px;
.lock-cost-tip-content {
min-height: 120px;
padding: 24px 20px;
box-sizing: border-box;
color: rgba(35, 35, 35, 0.8);
line-height: 20px;
font-size: 14px;
font-weight: 350;
}
.lock-cost-tip-footer {
height: 64px;
width: 100%;
border-top: 1px solid #eeeeee;
padding: 0px 20px;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: flex-end;
.cancel-btn,
.ok-btn {
height: 32px;
padding: 0px 16px;
border-radius: 4px;
box-sizing: border-box;
font-size: 14px;
font-weight: 350;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.cancel-btn {
margin-right: 12px;
color: rgba(35, 35, 35, 0.8);
border: 1px solid #dcdfe6;
}
.ok-btn {
background: #0081ff;
color: #fff;
}
}
}
}
}
</style>
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
<div class="cost-summary-container"> <div class="cost-summary-container">
<!-- 按项目汇总 成本汇总切换 --> <!-- 按项目汇总 成本汇总切换 -->
<div class="category-type-container"> <div class="category-type-container">
<div class="category-list-item" v-for="(type,index) of categoryList" :key="type.value" <div class="category-list-item" v-for="(type, index) of categoryList" :key="type.value"
:class="{'is-current-category' : currentCategory == type.value}" @click.stop="currentCategoryChange(type.value)">{{type.label}}</div> :class="{ 'is-current-category': currentCategory == type.value }" @click.stop="currentCategoryChange(type.value)">{{ type.label }}</div>
</div> </div>
<!-- 成本菜单以及列表 --> <!-- 成本菜单以及列表 -->
<div class="cost-summary-content-container"> <div class="cost-summary-content-container">
...@@ -26,8 +26,17 @@ ...@@ -26,8 +26,17 @@
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
<!-- 锁定成本 导出excel 编辑成本 -->
<div class="project-table-list-haeder-right"> <div class="project-table-list-haeder-right">
<div class="lock-cost-btn" :class="{ 'current-month-lock': currentMonthLock || !hasMenuData }"
@click="!currentMonthLock && hasMenuData ? lockCostHandler() : ''">锁定成本
</div>
<div class="export-excel-btn" :class="{'btn-is-disable' : !hasMenuData}" @click="!hasMenuData ? '' : exportExcel()">
导出Excel表</div>
<div class="edit-cost-btn" :class="{'btn-is-disable' : !hasMenuData}"
@click="hasMenuData ? (addActualCostEditStatus ? saveCostModify() : editCost()) : ''">
{{ addActualCostEditStatus ? "保存成本" : "编辑成本" }}
</div>
</div> </div>
</div> </div>
<!-- 数据列表部分 --> <!-- 数据列表部分 -->
...@@ -35,20 +44,47 @@ ...@@ -35,20 +44,47 @@
<dsk-skeleton v-if="tableLoading"></dsk-skeleton> <dsk-skeleton v-if="tableLoading"></dsk-skeleton>
<el-form :model="dataForm" ref="costSummaryForm" :show-message="false" v-else-if="!tableLoading" class="feed-summary-form"> <el-form :model="dataForm" ref="costSummaryForm" :show-message="false" v-else-if="!tableLoading" class="feed-summary-form">
<custom-table ref="costSummaryTable" :tableData="dataForm.tableDataList" :formColum="formColum" :max-height="true" :row-key="rowKey" <custom-table ref="costSummaryTable" :tableData="dataForm.tableDataList" :formColum="formColum" :max-height="true" :row-key="rowKey"
:lazy="true" :load-fn="tableLazyLoad" :tree-options="treeOptions" :default-expand-all="false" :indent="8" :tableDataTotal="total" :default-expand-all="true" :indent="8" :tableDataTotal="total" :paging="false" :cell-class-name="cellClassName">
:paging="false" :cell-class-name="cellClassName"> <!-- 本月费用(含税) -->
<template slot="taxInclusiveExpense" slot-scope="scope">
<!-- 本月费用(含税)编辑单元格 -->
<el-form-item :prop="`tableDataList.${getTableTreeProp(dataForm.tableDataList, scope.row.id)}.taxInclusiveExpense`"
:rules="checkRules.amountCheck" v-if="addActualCostEditStatus" class="inner-edit-input-item">
<el-input placeholder="请输入" v-model="scope.row.taxInclusiveExpense" clearable
@input="v => editIptValueRectify(v, scope.row, 'taxInclusiveExpense')"></el-input>
</el-form-item>
</template>
<!-- 本月费用(不含税) -->
<template slot="taxExclusiveExpense" slot-scope="scope">
<el-form-item :prop="`tableDataList.${getTableTreeProp(dataForm.tableDataList, scope.row.id)}.taxExclusiveExpense`"
:rules="checkRules.amountCheck" v-if="addActualCostEditStatus" class="inner-edit-input-item">
<el-input placeholder="请输入" v-model="scope.row.taxExclusiveExpense" clearable
@input="v => editIptValueRectify(v, scope.row, 'taxExclusiveExpense')"></el-input>
</el-form-item>
</template>
</custom-table> </custom-table>
</el-form> </el-form>
</div> </div>
</div> </div>
</div> </div>
<!-- 锁定前提示 -->
<lock-cost-tip v-model="lockCostTipDialog" :tip-content="lockCostTipDialogContent" @ok="okLock"
@update:lockCostTipDialog="lockCostTipDialogClose"></lock-cost-tip>
<!-- 选择编辑的成本月份弹窗 -->
<edit-cost-month-select v-model="editCostMonthSelectDialog" :project-create-time="projectDetailInfo.createTime" :disable-months="disableMonths"
@timeSelect="timeSelect" @dialogStatusChange="dialogStatusChange"></edit-cost-month-select>
</div> </div>
</template> </template>
<script> <script>
import ProjectSideMenu from "@/views/projectCostLedger/detail/components/ProjectSideMenu"; import ProjectSideMenu from "@/views/projectCostLedger/detail/components/ProjectSideMenu";
import DskSkeleton from "@/components/DskSkeleton"; import DskSkeleton from "@/components/DskSkeleton";
import CustomTable from "@/components/CustomTable"; import CustomTable from "@/components/CustomTable";
import { getCostSummaryMenuTreeApi, getCostSummaryMonthListApi, getCostSummaryListApi } from "@/api/projectCostLedger"; import EditCostMonthSelect from "@/views/projectCostLedger/detail/components/CostSummary/components/CostMonthSelect";
import LockCostTip from "@/views/projectCostLedger/detail/components/CostSummary/components/LockCostTip";
import { getCostSummaryMenuTreeApi, getCostSummaryMonthListApi, getCostSummaryAllListApi, validateBeforeCostLockApi, getLockMonthListApi, setCostLockApi, exportCostLockExcelApi, saveCostModifyApi } from "@/api/projectCostLedger";
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import dayjs from "dayjs"; import dayjs from "dayjs";
import { cloneDeep } from "lodash-es"; import { cloneDeep } from "lodash-es";
...@@ -97,9 +133,19 @@ export default { ...@@ -97,9 +133,19 @@ export default {
components: { components: {
ProjectSideMenu, ProjectSideMenu,
DskSkeleton, DskSkeleton,
CustomTable CustomTable,
LockCostTip,
EditCostMonthSelect
}, },
data() { data() {
const amountCheckValidator = (rule, value, callback) => {
// 有值才进行验证
if (value || value == "0") {
const reg = /^(?!0\d)(?!0*\.0*$)\d+(\.\d+)?$/;
if (!reg.test(value)) return callback(new Error("请输入正确的数值"));
}
callback();
};
return { return {
// 当前分类 1 按项目汇总 2 成本汇总 // 当前分类 1 按项目汇总 2 成本汇总
currentCategory: 1, currentCategory: 1,
...@@ -125,18 +171,26 @@ export default { ...@@ -125,18 +171,26 @@ export default {
total: 0, total: 0,
// 列表表头 // 列表表头
formColum: [ formColum: [
{ label: '序号', prop: "number", minWidth: "53", uid: v4() }, { label: '序号', prop: "number", minWidth: "80", uid: v4(), fixed: "left" },
{ label: '名称', prop: "cbName", width: "303", uid: v4(), showOverflowTooltip: true }, { label: '名称', prop: "cbName", width: "303", uid: v4(), showOverflowTooltip: true, fixed: "left" },
{ label: '不含税成本合价', prop: "taxExclusiveTotal", width: "182", uid: v4() },
{ label: '成本税金合价', prop: "cbTaxesTotal", width: "182", uid: v4() },
{ label: '含税成本合价', prop: "taxInclusiveTotal", width: "182", uid: v4() },
{ label: '成本占比', prop: "cbProportion", width: "182", uid: v4() },
{ label: '含税成本平米指标', prop: "taxInclusivePmTarget", width: "182", uid: v4() },
{ label: '备注', prop: "remark", width: "182", uid: v4() },
{ label: '本月费用(含税)', prop: "taxInclusiveExpense", width: "182", uid: v4(), slot: true },
{ label: '本月费用(不含税)', prop: "taxExclusiveExpense", width: "182", uid: v4(), slot: true },
{ label: '截止本月费用(含税)', prop: "taxInclusiveExpenseTotal", width: "182", uid: v4() },
{ label: '截止本月费用(不含税)', prop: "taxExclusiveExpenseTotal", width: "182", uid: v4() },
], ],
monthList: [], monthList: [],
rowKey: "id",
// 列表懒加载配置
treeOptions: {
children: "children",
hasChildren: "hasChildren"
},
// 源数据月份 // 源数据月份
originMonthList: [], originMonthList: [],
// 已经锁定的成本月份
lockMonthList: [],
rowKey: "id",
// 列表懒加载配置
dataForm: { dataForm: {
// 数据列表源数据 // 数据列表源数据
tableDataList: [], tableDataList: [],
...@@ -146,17 +200,31 @@ export default { ...@@ -146,17 +200,31 @@ export default {
// 历史查询月份 // 历史查询月份
oldExpenseDate: "", oldExpenseDate: "",
// 当前选中子菜单的父类名称 // 当前选中子菜单的父类名称
currentParentName: "", currentParentId: "",
// 当前选中的成本科目 // 当前选中的成本科目
currentNodeValue: "", currentNodeValue: "",
// 源数据列表 // 源数据列表
originTableDataList: [], originTableDataList: [],
// 填写成本弹窗
showAddActualCost: false,
// 填写成本 编辑状态 // 填写成本 编辑状态
addActualCostEditStatus: false, addActualCostEditStatus: false,
// 当前选择的成本年份 // 当前选择的成本年份
selectActualCostTime: "", selectActualCostTime: "",
// 锁定成本前提示弹窗
lockCostTipDialog: false,
// 锁定成本前提示弹窗文本内容
lockCostTipDialogContent: "",
// 编辑成本选择月份弹窗
editCostMonthSelectDialog: false,
// 被锁定的成本月份
disableMonths: [],
// 编辑数据验证规则
checkRules: {
amountCheck: [
{ trigger: ["change"], validator: amountCheckValidator }
]
},
// 竖向滚动条最后的位置
lastScrollTop: 0
}; };
}, },
//可访问data属性 //可访问data属性
...@@ -165,7 +233,14 @@ export default { ...@@ -165,7 +233,14 @@ export default {
}, },
//计算集 //计算集
computed: { computed: {
// 查看当前月是否是锁定状态 lock为true 不能锁定 反之可以
currentMonthLock() {
return this.lockMonthList.includes(this.expenseDate);
},
// 是否有科目菜单
hasMenuData() {
return this.menuTreeList.length ? true : false;
}
}, },
//方法集 //方法集
methods: { methods: {
...@@ -186,15 +261,29 @@ export default { ...@@ -186,15 +261,29 @@ export default {
}, },
// 返回当前月是否在server month集合中 // 返回当前月是否在server month集合中
includeNowMonth(time) { includeNowMonth(time) {
return this.originMonthList.includes(time); return this.originMonthList.find(item => item.expenseDate == time);
}, },
// 按项目汇总 按成本科目汇总
currentCategoryChange(category) { currentCategoryChange(category) {
if (category == this.currentCategory) return; if (category == this.currentCategory) return;
this.currentCategory = category; this.currentCategory = category;
this.resetEditStatus();
this.tableLoading = true;
this.resetTableData();
this.init(this.comProjectDetailInfo);
}, },
async init(detail = {}, resetDate = "") { resetTableData() {
this.$set(this.dataForm, "tableDataList", []);
const data = this.$options.data.call(this);
this.originTableDataList = data.originTableDataList;
this.total = 0;
this.monthList = data.monthList;
this.originMonthList = data.originMonthList;
this.disableMonths = data.disableMonths;
},
async init(detail = {}, resetDate = "", saveReset = false) {
try { try {
this.resetEditStatus(); this.resetEditStatus(saveReset);
const { projectId, cbStage } = detail; const { projectId, cbStage } = detail;
if (!projectId) return; if (!projectId) return;
const params = { const params = {
...@@ -203,25 +292,26 @@ export default { ...@@ -203,25 +292,26 @@ export default {
cbType: this.currentCategory cbType: this.currentCategory
}; };
await this.getCostSummaryMenuTree(params); await this.getCostSummaryMenuTree(params);
await this.getCostSummaryMonthList(params); await this.getCostSummaryMonthList(params, saveReset);
await this.initDefaultSetting(resetDate); await this.getLockMonthList(params);
await this.initDefaultSetting(resetDate, saveReset);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} finally { } finally {
this.tableLoading = false; this.tableLoading = false;
} }
}, },
async initDefaultSetting(resetDate = "") { async initDefaultSetting(resetDate = "", saveReset = false) {
try { try {
await this.$nextTick(); await this.$nextTick();
const first = this.$refs["projectSideMenu"].getFirstLevelWithDeepId(); const first = saveReset ? this.currentNodeValue : this.$refs["projectSideMenu"].getFirstLevelWithDeepId();
const menus = this.$refs["projectSideMenu"].getResultMenuList(); const menus = this.$refs["projectSideMenu"].getResultMenuList();
const defaultCurrent = this.findMenuNode(menus, first); const defaultCurrent = this.findMenuNode(menus, first);
// 默认选中结构劳务分包 // 默认选中第一层级 第一个子菜单
if (defaultCurrent) { if (defaultCurrent) {
this.currentNodeValue = defaultCurrent.nodeValue; this.currentNodeValue = defaultCurrent.nodeValue;
const parentName = defaultCurrent.parent ? this.getCurrentType(defaultCurrent.parent) : defaultCurrent.nodeName; const parentId = defaultCurrent.parent ? this.getCurrentType(defaultCurrent.parent) : defaultCurrent.nodeName;
if (parentName) this.currentParentName = parentName; if (parentId) this.currentParentId = parentId;
const params = this.createRequestConditions(resetDate); const params = this.createRequestConditions(resetDate);
await this.getCostSummaryList(params); await this.getCostSummaryList(params);
} }
...@@ -231,7 +321,7 @@ export default { ...@@ -231,7 +321,7 @@ export default {
}, },
getCurrentType(parent) { getCurrentType(parent) {
if (parent.level == 2) { if (parent.level == 2) {
return parent.nodeName; return parent.nodeValue;
} }
if (parent.parent) { if (parent.parent) {
return this.getCurrentType(parent.parent); return this.getCurrentType(parent.parent);
...@@ -242,9 +332,10 @@ export default { ...@@ -242,9 +332,10 @@ export default {
if (item[targetName] == nodeValue) return item; if (item[targetName] == nodeValue) return item;
if (item.children instanceof Array) { if (item.children instanceof Array) {
const result = this.findMenuNode(item.children, nodeValue, targetName); const result = this.findMenuNode(item.children, nodeValue, targetName);
if (result) return result; return result;
} }
} }
return null;
}, },
// 创建查询条件 // 创建查询条件
createRequestConditions(resetDate = "") { createRequestConditions(resetDate = "") {
...@@ -274,25 +365,26 @@ export default { ...@@ -274,25 +365,26 @@ export default {
cbName: this.currentCategory == 1 ? "成本汇总" : "房建类成本科目", cbName: this.currentCategory == 1 ? "成本汇总" : "房建类成本科目",
children: _tempArray children: _tempArray
}; };
this.menuTreeList = [_tempMenu]; this.menuTreeList = _tempArray.length ? [_tempMenu] : [];
} }
} catch (error) { } catch (error) {
} }
}, },
async getCostSummaryMonthList(params) { async getCostSummaryMonthList(params, saveReset = false) {
try { try {
const monthList = await getCostSummaryMonthListApi(params); const monthList = await getCostSummaryMonthListApi(params);
if (monthList.code == 200 && monthList.data instanceof Array) { if (monthList.code == 200 && monthList.data instanceof Array) {
const data = monthList.data; const data = monthList.data;
this.originMonthList = cloneDeep(data); this.originMonthList = cloneDeep(data);
const _now = this.getNowMonth(); const _now = this.getNowMonth();
this.expenseDate = _now; this.expenseDate = saveReset ? this.expenseDate : _now;
// 默认以当前月数据为准 若不包含当前月 需要手动push数据 // 默认以当前月数据为准 若不包含当前月 需要手动push数据
if (!data.includes(_now)) { if (!data.find(item => item.expenseDate == _now)) {
data.push({ data.push({
label: dayjs(_now).format("YYYY年MM月"),
expenseDate: _now, expenseDate: _now,
isLock: 0 isLock: 0,
}); });
} }
// 年月排序 // 年月排序
...@@ -310,6 +402,17 @@ export default { ...@@ -310,6 +402,17 @@ export default {
} }
}, },
// 获得已锁定锁定成本月
async getLockMonthList(params) {
try {
const lockMonth = await getLockMonthListApi(params);
if (lockMonth.code == 200 && lockMonth.data instanceof Array) {
this.lockMonthList = lockMonth.data;
}
} catch (error) {
}
},
monthChange(month) { monthChange(month) {
// 当前月 // 当前月
const _now = this.getNowMonth(); const _now = this.getNowMonth();
...@@ -339,50 +442,65 @@ export default { ...@@ -339,50 +442,65 @@ export default {
async getCostSummaryList(params = {}) { async getCostSummaryList(params = {}) {
try { try {
this.tableLoading = true; this.tableLoading = true;
const list = await getCostSummaryListApi(params); const list = await getCostSummaryAllListApi(params);
if (list.code == 200 && list.data instanceof Array) { if (list.code == 200 && list.data instanceof Array) {
let _temp = list.data; let _temp = list.data;
const _mapList = new Map(); //! 注释代码 皆为 懒加载情况下处理逻辑
// 如果有长度循环处理字段 // const _mapList = new Map();
if (_temp.length) { // // 如果有长度循环处理字段
_temp = _temp.map(item => { // if (_temp.length) {
if (!item.hasChildren) { // _temp = _temp.map(item => {
item.hasChildren = false; // if (!item.hasChildren) {
} else { // item.hasChildren = false;
// 有children // } else {
item.hasChildren = true; // // 有children
if (item?.children?.length) { // item.hasChildren = true;
item.children = item.children.map(childItem => { // if (item?.children?.length) {
childItem.hasChildren = childItem.hasChildren ? true : false; // item.children = item.children.map(childItem => {
return childItem; // childItem.hasChildren = childItem.hasChildren ? true : false;
}); // return childItem;
} // });
}; // }
// 储存将子级储存到map 主动调用展开菜单 // };
item.hasChildren ? _mapList.set(item.id, item.children ? cloneDeep(item.children) : []) : null; // // 储存将子级储存到map 主动调用展开菜单
delete item.children; // item.hasChildren ? _mapList.set(item.id, item.children ? cloneDeep(item.children) : []) : null;
return item; // delete item.children;
}); // return item;
} // });
console.log(_temp); // }
this.$set(this.dataForm, "tableDataList", cloneDeep(_temp)); this.$set(this.dataForm, "tableDataList", cloneDeep(_temp));
this.originTableDataList = cloneDeep(_temp); this.originTableDataList = cloneDeep(_temp);
this.total = _temp.length; this.total = _temp.length;
this.tableLoading = false; this.tableLoading = false;
await this.$nextTick(); // await this.$nextTick();
const tableIns = this.$refs["costSummaryTable"].$refs["customTableRef"]; // const tableIns = this.$refs["costSummaryTable"].$refs["customTableRef"];
if (tableIns) { // if (tableIns) {
_mapList.forEach((child, id) => { // _mapList.forEach((child, id) => {
// 打开一级目录 // // 打开一级目录
this.customResolve(id, child, tableIns); // this.customResolve(id, child, tableIns);
}); // });
} // }
} }
} catch (error) { } catch (error) {
this.tableLoading = false; this.tableLoading = false;
console.log(error); console.log(error);
} }
}, },
// 将需要编辑的值 设置为默认值 0
setEditPropDefaultValue(list = [], editPropsArray = []) {
const result = list.map(item => {
editPropsArray.forEach(prop => {
if (!item[prop]) {
item[prop] = 0;
}
});
if (item?.children?.length) {
this.setEditPropDefaultValue(item?.children, editPropsArray);
}
return item;
});
return result;
},
// 模拟 resolve 懒加载 // 模拟 resolve 懒加载
customResolve(id, child, tableIns) { customResolve(id, child, tableIns) {
let children = child; let children = child;
...@@ -403,8 +521,8 @@ export default { ...@@ -403,8 +521,8 @@ export default {
this.$set(treeData, newKey, metaInfo); this.$set(treeData, newKey, metaInfo);
//lazyTreeNodeMap中 添加数据 //lazyTreeNodeMap中 添加数据
this.$set(treeNodeMap, newKey, children); this.$set(treeNodeMap, newKey, children);
console.log(treeData, "treeData"); // console.log(treeData, "treeData");
console.log(treeNodeMap, "treeNodeMap"); // console.log(treeNodeMap, "treeNodeMap");
}, },
async getCostSummaryListLazy(params = {}) { async getCostSummaryListLazy(params = {}) {
try { try {
...@@ -446,9 +564,10 @@ export default { ...@@ -446,9 +564,10 @@ export default {
} }
}, },
// 编辑状态下 进行了其它操作 // 编辑状态下 进行了其它操作
resetEditStatus() { resetEditStatus(saveReset = false) {
// 当前需要编辑或者新增的成本年份 // 当前需要编辑或者新增的成本年份
const _selectActualCostTime = this.selectActualCostTime; const _selectActualCostTime = this.selectActualCostTime;
this.editCostMonthSelectDialog = false;
this.addActualCostEditStatus = false; this.addActualCostEditStatus = false;
this.selectActualCostTime = ""; this.selectActualCostTime = "";
/** /**
...@@ -456,9 +575,9 @@ export default { ...@@ -456,9 +575,9 @@ export default {
* 默认本月 * 默认本月
*/ */
if (!_selectActualCostTime) return; if (!_selectActualCostTime) return;
if (!this.originMonthList.includes(_selectActualCostTime) && _selectActualCostTime != this.getNowMonth()) { if (!this.originMonthList.find(item => item.expenseDate == _selectActualCostTime) && _selectActualCostTime != this.getNowMonth()) {
const index = this.monthList.findIndex(item => item.value == _selectActualCostTime); const index = this.monthList.findIndex(item => item.expenseDate == _selectActualCostTime);
if (index != -1) { if (index != -1 && !saveReset) {
this.monthList.splice(index, 1); this.monthList.splice(index, 1);
this.expenseDate = this.getNowMonth(); this.expenseDate = this.getNowMonth();
} }
...@@ -467,13 +586,233 @@ export default { ...@@ -467,13 +586,233 @@ export default {
async menuSelect(currentId, currentTemp) { async menuSelect(currentId, currentTemp) {
this.resetEditStatus(); this.resetEditStatus();
this.currentNodeValue = currentId; this.currentNodeValue = currentId;
const parentName = currentTemp.parent ? this.getCurrentType(currentTemp.parent) : currentId; const parentId = currentTemp.parent ? this.getCurrentType(currentTemp.parent) : currentId;
if (parentName) this.currentParentName = parentName; if (parentId) this.currentParentId = parentId;
const params = this.createRequestConditions(this.expenseDate); const params = this.createRequestConditions(this.expenseDate);
this.getCostSummaryList(params); this.getCostSummaryList(params);
}, },
// 锁定成本
async lockCostHandler() {
try {
const { cbType, projectId } = this.createRequestConditions();
const params = {
expenseDate: this.expenseDate,
cbType,
projectId
};
const tip = await validateBeforeCostLockApi(params);
if (tip.code == 200 && tip.data == 500) {
this.lockCostTipDialogContent = tip.msg;
this.lockCostTipDialog = true;
return;
}
} catch (error) {
}
}, },
} // 锁定成本弹窗关闭
lockCostTipDialogClose() {
this.lockCostTipDialogContent = "";
this.lockCostTipDialog = false;
},
// 确定锁定成本
async okLock() {
try {
const { cbType, projectId } = this.createRequestConditions();
const params = {
expenseDate: this.expenseDate,
cbType,
projectId
};
const lockResult = await setCostLockApi(params);
if (lockResult.code == 200) {
this.$message.success("锁定成功");
this.lockCostTipDialog = false;
const params = this.createRequestConditions();
await this.getLockMonthList(params);
}
this.resetEditStatus();
} catch (error) {
}
},
// 导出excel
async exportExcel() {
try {
const { cbType, projectId } = this.createRequestConditions();
const params = {
expenseDate: this.expenseDate,
cbType,
projectId
};
let { data, fileName } = await exportCostLockExcelApi(params);
if (data && fileName) {
fileName = fileName.split(";")[1].split("filename=")[1];
this.$download.saveAs(data, decodeURIComponent(fileName));
}
} catch (error) {
console.log(error);
}
},
// 编辑成本
editCost() {
// const _disableMonths = this.monthList.filter(item => item.isLock == true).map(item => item.expenseDate);
const _disableMonths = cloneDeep(this.lockMonthList);
this.disableMonths = _disableMonths;
this.editCostMonthSelectDialog = true;
},
dialogStatusChange(flag) {
this.editCostMonthSelectDialog = false;
// 重置禁用
this.disableMonths = [];
},
//成本月选择回调
async timeSelect(selectTime) {
// 编辑状态
this.addActualCostEditStatus = true;
this.selectActualCostTime = selectTime;
// 判断是否包含 选择的年月 包含则修改 未包含则新增
const findReslut = this.originMonthList.find(item => item.expenseDate == selectTime) || this.monthList.find(item => item.expenseDate == selectTime);
const params = this.createRequestConditions();
if (!findReslut) {
// 不包含当前所选月 新增数据
let _temp = JSON.parse(JSON.stringify(this.monthList));
_temp.push({
label: dayjs(selectTime).format("YYYY年MM月"),
expenseDate: selectTime,
isLock: 0
});
_temp = this.monthsSort(_temp);
// console.log(_temp);
this.monthList = _temp;
}
this.expenseDate = selectTime;
params["expenseDate"] = selectTime;
// 获取选中月数据
await this.getCostSummaryList(params);
// 将编辑区域移动到视口
await this.$nextTick();
await this.editRegionToViewPort();
},
// 将编辑区域移动到视口
async editRegionToViewPort() {
// 获取编辑列所处位置
const container = document.querySelector(".el-table__body-wrapper");
/**
* @type {HTMLTableCellElement}
*/
const editElement = container.querySelector(".el-table__row [class *= can-edit-column-]");
if (editElement) {
const left = editElement.offsetLeft;
container.scrollTo({
behavior: "smooth",
left,
top: this.lastScrollTop
});
this.lastScrollTop = 0;
}
},
// 成本输入数据限制
editIptValueRectify(value, row, prop) {
const reg = /^(?!0\d)(?!0+$)(?!0*\.0*$)\d+(\.\d+)?$/;
if (reg.test(value)) {
row[prop] = add(0, value);
}
},
//保存成本
saveCostModify() {
this.$refs["costSummaryForm"].validate(async flag => {
if (flag) {
// 进行差异化对比
let resultData = this.differentCompare();
// 没有差异
if (!resultData.length) {
this.resetEditStatus();
const params = this.createRequestConditions(this.expenseDate);
await this.getCostSummaryList(params);
return;
}
// 有差异数据 记录滚动条滚动位置
await this.getLastScrollTop();
const result = await saveCostModifyApi(resultData);
if (result.code == 200) {
this.$message.success("保存成功");
await this.init(this.comProjectDetailInfo, this.expenseDate, true);
await this.$nextTick();
await this.editRegionToViewPort();
}
}
});
},
//获取竖向滚动条最后的位置
async getLastScrollTop() {
const table = document.querySelector(".custom-table .el-table__body-wrapper");
if (table) {
this.lastScrollTop = table.scrollTop;
}
},
// 差异化比对
differentCompare() {
const originData = this.originTableDataList;
/**
* @type {Array<object>}
*/
let data = cloneDeep(this.dataForm.tableDataList);
// 差异数据
const different = this.getDeepDifferentData(data, originData);
return cloneDeep(different);
},
// 深度差异化对比
getDeepDifferentData(data = [], originData = [], tempArray = []) {
const len = data.length;
for (let index = 0; index < len; index++) {
const item = data[index];
// 源数据
const originItem = originData[index];
// 查看可编辑字段是否存在任意一处 数据不同
const hasDifferent = editPropNames.some(prop => {
// 两个皆为无效值 返回false
if (!parseFloat(item[prop]) && !parseFloat(originItem[prop])) return false;
return item[prop] != originItem[prop];
});
// 浅层级
if (hasDifferent) {
tempArray.push({
id: item.actualId,
cbSummaryId: item.id,
taxInclusiveExpense: item.taxInclusiveExpense ? item.taxInclusiveExpense : 0,
taxExclusiveExpense: item.taxExclusiveExpense ? item.taxExclusiveExpense : 0,
expenseDate: this.expenseDate
});
}
// 递归深层级
if (item?.children?.length) {
this.getDeepDifferentData(item.children, originItem.children, tempArray);
}
}
return tempArray;
},
// 获取当前树形结构下 输入框prop的完整路径
getTableTreeProp(dataList = [], rowId, pathArray = []) {
const len = dataList.length;
for (let index = 0; index < len; index++) {
const item = dataList[index];
// 返回所在下标index
if (item.id === rowId) {
return [...pathArray, index].join("");
}
if (item?.children?.length) {
const childPath = [...pathArray, index, '.children.'];
const result = this.getTableTreeProp(item.children, rowId, childPath);
if (result) {
return result;
}
}
}
return null;
},
},
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.cost-summary-container { .cost-summary-container {
...@@ -555,8 +894,10 @@ export default { ...@@ -555,8 +894,10 @@ export default {
.project-table-list-haeder-left { .project-table-list-haeder-left {
display: flex; display: flex;
align-items: center; align-items: center;
.project-month-select-options { .project-month-select-options {
width: 140px; width: 140px;
.el-input__inner { .el-input__inner {
height: 32px; height: 32px;
line-height: 32px; line-height: 32px;
...@@ -567,13 +908,16 @@ export default { ...@@ -567,13 +908,16 @@ export default {
color: #232323; color: #232323;
font-weight: 350; font-weight: 350;
} }
.el-input__suffix { .el-input__suffix {
right: 12px; right: 12px;
.el-input__icon { .el-input__icon {
line-height: 32px; line-height: 32px;
width: auto; width: auto;
} }
} }
.el-input__prefix { .el-input__prefix {
display: none; display: none;
} }
...@@ -584,13 +928,14 @@ export default { ...@@ -584,13 +928,14 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
.actual-cost-btn, .lock-cost-btn,
.unit-conversion-btn { .export-excel-btn,
.edit-cost-btn {
height: 32px; height: 32px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 0px 12px; padding: 0px 16px;
background-color: #0081ff; background-color: #0081ff;
border-color: #0081ff; border-color: #0081ff;
border-radius: 4px; border-radius: 4px;
...@@ -598,6 +943,27 @@ export default { ...@@ -598,6 +943,27 @@ export default {
font-size: 14px; font-size: 14px;
font-weight: 350; font-weight: 350;
margin-right: 16px; margin-right: 16px;
cursor: pointer;
}
.lock-cost-btn {
/* 当前月锁定 */
&.current-month-lock {
cursor: not-allowed;
background: #66b3ff;
}
}
.edit-cost-btn {
margin-right: 0px;
}
.edit-cost-btn,
.export-excel-btn {
&.btn-is-disable {
cursor: not-allowed;
background: #66b3ff;
}
} }
} }
} }
...@@ -623,19 +989,23 @@ export default { ...@@ -623,19 +989,23 @@ export default {
th { th {
height: 40px; height: 40px;
} }
.cell { .cell {
font-size: 14px; font-size: 14px;
font-weight: 350; font-weight: 350;
} }
.number-index-td { .number-index-td {
.cell { .cell {
display: flex; display: flex;
align-items: center; align-items: center;
.el-table__expand-icon { .el-table__expand-icon {
margin-right: 5px; margin-right: 5px;
} }
} }
} }
.inner-edit-input-item { .inner-edit-input-item {
margin-bottom: 0px; margin-bottom: 0px;
...@@ -661,6 +1031,7 @@ export default { ...@@ -661,6 +1031,7 @@ export default {
border-color: #0081ff; border-color: #0081ff;
} }
} }
.el-input__clear { .el-input__clear {
line-height: 32px; line-height: 32px;
} }
......
<template> <template>
<el-dialog title="填写实际成本" :visible="comDialogStatus" class="add-actual-cost-container" @close="dialogClose"> <el-dialog title="填写实际成本" :visible="comDialogStatus" class="add-actual-cost-container" @close="dialogClose" :destroy-on-close="true"
<div class="dialog-content-inner"> :close-on-click-modal="false">
<div class=" dialog-content-inner">
<!-- 成本年份 --> <!-- 成本年份 -->
<div class="cost-year-container"> <div class="cost-year-container">
<span>成本年份</span> <span>成本年份</span>
...@@ -93,7 +94,7 @@ export default { ...@@ -93,7 +94,7 @@ export default {
// 当前项目月份 补0 // 当前项目月份 补0
const _thresholdMonth = _thresholdTime.slice(4); const _thresholdMonth = _thresholdTime.slice(4);
// 是否小于当前项目年月 或 大于 当前项目年月 往后推五年 // 是否小于当前项目年月 或 大于 当前项目年月 往后推五年
const lastYearMonth = parseInt(`${parseInt(_thresholdYear) + 5}${_thresholdMonth}`);; const lastYearMonth = parseInt(`${parseInt(_thresholdYear) + 5}${_thresholdMonth}`);
if (parseInt(_optionTime) < parseInt(_thresholdTime) || parseInt(_optionTime) > lastYearMonth) { if (parseInt(_optionTime) < parseInt(_thresholdTime) || parseInt(_optionTime) > lastYearMonth) {
return true; return true;
} }
......
...@@ -4,17 +4,17 @@ ...@@ -4,17 +4,17 @@
<div class="dialog-body-content"> <div class="dialog-body-content">
<el-form :model="pushForm" ref="pushForm" :rules="rules" class="push-form"> <el-form :model="pushForm" ref="pushForm" :rules="rules" class="push-form">
<el-form-item label="分包项目名称"> <el-form-item label="分包项目名称">
<el-input :value="pushForm.projectDetailInfo.projectName" :disabled="true"></el-input> <el-input :value="pushForm.projectName" :disabled="true"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="本月实际工程量"> <el-form-item label="本月实际工程量">
<el-input :value="pushForm.totalQuantities" :disabled="true"></el-input> <el-input :value="pushForm.totalQuantities" :disabled="true"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="需推送工程量" prop="pushQuantities" :rules="pushQuantitiesValidator(pushForm.totalQuantities)"> <el-form-item label="需推送工程量" prop="pushQuantities" :rules="pushQuantitiesValidator(pushForm.totalQuantities)">
<el-input v-model="pushForm.pushQuantities" placeholder="请填写需推送工程量"></el-input> <el-input v-model="pushForm.pushQuantities" @input="pushQuantitiesIpt" placeholder="请填写需推送工程量"></el-input>
</el-form-item> </el-form-item>
<!-- ipm项目编码 --> <!-- ipm项目编码 -->
<el-form-item label="IPM项目编码"> <el-form-item label="IPM项目编码">
<el-input v-model="pushForm.projectDetailInfo.ipmProjectNo" placeholder="请输入IPM项目编码"></el-input> <el-input v-model="pushForm.ipmProjectCode" placeholder="请输入IPM项目编码"></el-input>
</el-form-item> </el-form-item>
<!-- ipm合同编码 --> <!-- ipm合同编码 -->
<el-form-item label="IPM合同编码"> <el-form-item label="IPM合同编码">
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
</el-dialog> </el-dialog>
</template> </template>
<script> <script>
import { subtract, targetIsNegative } from "@/utils/decimal"; import { subtract, targetIsNegative, add } from "@/utils/decimal";
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
export default { export default {
name: "pushProjectUseDialog", name: "pushProjectUseDialog",
...@@ -80,15 +80,12 @@ export default { ...@@ -80,15 +80,12 @@ export default {
comPushProjectUseDialog: this.pushProjectUseDialog, comPushProjectUseDialog: this.pushProjectUseDialog,
pushForm: { pushForm: {
id: "", id: "",
projectName: "",
totalQuantities: "",
pushQuantities: "", pushQuantities: "",
ipmProjectCode: "", ipmProjectCode: "",
ipmContractCode: "", ipmContractCode: "",
ipmBizCode: "", ipmBizCode: "",
totalQuantities: "",
projectDetailInfo: {
projectName: "",
ipmProjectNo: ""
}
}, },
rules: {} rules: {}
}; };
...@@ -115,11 +112,20 @@ export default { ...@@ -115,11 +112,20 @@ export default {
} }
}]; }];
}, },
pushQuantitiesIpt(value) {
const reg = /^(?!0\d)(?!0+$)(?!0*\.0*$)\d+(\.\d+)?$/;
if (reg.test(value)) {
this.pushForm.pushQuantities = add(0, value);
}
},
clearValidate() {
const form = this.$refs["pushForm"];
if (form) form.clearValidate();
},
dialogClose() { dialogClose() {
this.$emit("dialogClose"); this.$emit("dialogClose");
this.pushForm = this.$options.data.call(this).pushForm; this.pushForm = this.$options.data.call(this).pushForm;
const form = this.$refs["pushForm"]; this.clearValidate();
if (form) form.clearValidate();
this.$emit("close", false); this.$emit("close", false);
}, },
dialogOpen() { dialogOpen() {
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
<template slot="action-field-bar" slot-scope="scope"> <template slot="action-field-bar" slot-scope="scope">
<div class="project-action-field-bar" v-if="rowCanEditInput(scope.rowIndex,hasTarget)"> <div class="project-action-field-bar" v-if="rowCanEditInput(scope.rowIndex,hasTarget)">
<span class="push-project-use" :class="{'is-emty-quantities' : rowHasLastPush(scope.rowIndex)}" <span class="push-project-use" :class="{'is-emty-quantities' : rowHasLastPush(scope.rowIndex)}"
@click="parseFloat(scope.row.quantities) ? pushProjectUse(scope.row) : ''">推送工程量</span> @click="!rowHasLastPush(scope.rowIndex) ? pushProjectUse(scope.row) : ''">推送工程量</span>
</div> </div>
<span v-else>-</span> <span v-else>-</span>
</template> </template>
...@@ -51,7 +51,8 @@ ...@@ -51,7 +51,8 @@
<!-- 编辑单元格 --> <!-- 编辑单元格 -->
<el-form-item :prop="`tableDataList.${scope.rowIndex}.quantities`" :rules="checkRules.amountCheck" <el-form-item :prop="`tableDataList.${scope.rowIndex}.quantities`" :rules="checkRules.amountCheck"
v-if="rowCanEditInput(scope.rowIndex,hasTarget) && addActualCostEditStatus" class="inner-edit-input-item"> v-if="rowCanEditInput(scope.rowIndex,hasTarget) && addActualCostEditStatus" class="inner-edit-input-item">
<el-input placeholder="请输入" v-model="scope.row.quantities" clearable @input="v => statisticsSum(v,'quantities')"></el-input> <el-input placeholder="请输入" v-model="scope.row.quantities" clearable
@input="v => statisticsSum(v,'quantities',scope.row)"></el-input>
</el-form-item> </el-form-item>
</template> </template>
<!-- 本月采购单价 --> <!-- 本月采购单价 -->
...@@ -60,7 +61,7 @@ ...@@ -60,7 +61,7 @@
<el-form-item :prop="`tableDataList.${scope.rowIndex}.purchaseUnitPrice`" :rules="checkRules.amountCheck" <el-form-item :prop="`tableDataList.${scope.rowIndex}.purchaseUnitPrice`" :rules="checkRules.amountCheck"
v-if="rowCanEditInput(scope.rowIndex,hasTarget) && addActualCostEditStatus" class="inner-edit-input-item"> v-if="rowCanEditInput(scope.rowIndex,hasTarget) && addActualCostEditStatus" class="inner-edit-input-item">
<el-input placeholder="请输入" v-model="scope.row.purchaseUnitPrice" clearable <el-input placeholder="请输入" v-model="scope.row.purchaseUnitPrice" clearable
@input="v => statisticsSum(v,'purchaseUnitPrice')"></el-input> @input="v => statisticsSum(v,'purchaseUnitPrice',scope.row)"></el-input>
</el-form-item> </el-form-item>
</template> </template>
</custom-table> </custom-table>
...@@ -208,9 +209,9 @@ export default { ...@@ -208,9 +209,9 @@ export default {
{ label: '指导价格', prop: "guidePrice", minWidth: "81", uid: v4() }, { label: '指导价格', prop: "guidePrice", minWidth: "81", uid: v4() },
{ label: '投标选用单价(不含税)', prop: "bidUnitPrice", minWidth: "179", uid: v4() }, { label: '投标选用单价(不含税)', prop: "bidUnitPrice", minWidth: "179", uid: v4() },
{ label: '单价差额', prop: "unitPriceDifference", minWidth: "81", uid: v4() }, { label: '单价差额', prop: "unitPriceDifference", minWidth: "81", uid: v4() },
{ label: '数量', prop: "quantity", minWidth: "53", uid: v4() }, { label: '数量', prop: "quantity", minWidth: "150", uid: v4() },
{ label: '合价(不含税)', prop: "combinedPrice", minWidth: "123", uid: v4() }, { label: '合价(不含税)', prop: "combinedPrice", minWidth: "150", uid: v4() },
{ label: '合价(含税)', prop: "combinedPriceTax", minWidth: "109", uid: v4() }, { label: '合价(含税)', prop: "combinedPriceTax", minWidth: "150", uid: v4() },
{ label: '品牌名称', prop: "brandName", minWidth: "81", uid: v4() }, { label: '品牌名称', prop: "brandName", minWidth: "81", uid: v4() },
{ label: '投标选用来源', prop: "bidSource", minWidth: "109", uid: v4() }, { label: '投标选用来源', prop: "bidSource", minWidth: "109", uid: v4() },
] ]
...@@ -257,10 +258,20 @@ export default { ...@@ -257,10 +258,20 @@ export default {
addActualCostEditStatus: false, addActualCostEditStatus: false,
// 当前选择的成本年份 // 当前选择的成本年份
selectActualCostTime: "", selectActualCostTime: "",
lastScrollTop: 0,
// 推送工程量弹窗 // 推送工程量弹窗
pushProjectUseDialog: false, pushProjectUseDialog: false,
// 推送工程量数据缓存 // 推送工程量数据缓存
pushProjectUseTemp: {}, pushProjectUseTemp: {
id: "",
pushQuantities: "",
ipmProjectCode: "",
ipmContractCode: "",
ipmBizCode: "",
totalQuantities: "",
projectName: "",
ipmProjectNo: ""
},
checkRules: { checkRules: {
amountCheck: [ amountCheck: [
{ trigger: ["change"], validator: amountCheckValidator } { trigger: ["change"], validator: amountCheckValidator }
...@@ -292,9 +303,9 @@ export default { ...@@ -292,9 +303,9 @@ export default {
}, },
//方法集 //方法集
methods: { methods: {
async init(detail = {}, resetDate = "") { async init(detail = {}, resetDate = "", saveReset = false) {
try { try {
this.resetEditStatus(); this.resetEditStatus(saveReset);
const { projectId, cbStage } = detail; const { projectId, cbStage } = detail;
if (!projectId) return; if (!projectId) return;
const params = { const params = {
...@@ -302,19 +313,19 @@ export default { ...@@ -302,19 +313,19 @@ export default {
cbStage cbStage
}; };
await this.getFeedSummaryMenuTree(params); await this.getFeedSummaryMenuTree(params);
await this.getFeedSummaryMonthList(params); await this.getFeedSummaryMonthList(params, saveReset);
await this.initDefaultSetting(resetDate); await this.initDefaultSetting(resetDate, saveReset);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} finally { } finally {
this.tableLoading = false; this.tableLoading = false;
} }
}, },
async initDefaultSetting(resetDate = "") { async initDefaultSetting(resetDate = "", saveReset = false) {
try { try {
await this.$nextTick(); await this.$nextTick();
const menus = this.$refs["projectSideMenu"].getResultMenuList(); const menus = this.$refs["projectSideMenu"].getResultMenuList();
const defaultCurrent = this.findMenuNode(menus, "结构劳务分包"); const defaultCurrent = this.findMenuNode(menus, saveReset ? this.currentNodeName : "结构劳务分包");
// 默认选中结构劳务分包 // 默认选中结构劳务分包
if (defaultCurrent) { if (defaultCurrent) {
this.currentNodeName = defaultCurrent.nodeName; this.currentNodeName = defaultCurrent.nodeName;
...@@ -417,14 +428,14 @@ export default { ...@@ -417,14 +428,14 @@ export default {
} }
}, },
async getFeedSummaryMonthList(params) { async getFeedSummaryMonthList(params, saveReset = false) {
try { try {
const monthList = await getFeedSummaryMonthListApi(params); const monthList = await getFeedSummaryMonthListApi(params);
if (monthList.code == 200 && monthList.data instanceof Array) { if (monthList.code == 200 && monthList.data instanceof Array) {
const data = monthList.data; const data = monthList.data;
this.originMonthList = cloneDeep(data); this.originMonthList = cloneDeep(data);
const _now = this.getNowMonth(); const _now = this.getNowMonth();
this.recordDate = _now; this.recordDate = saveReset ? this.recordDate : _now;
// this.oldRecordDate = _now; // this.oldRecordDate = _now;
// 默认以当前月数据为准 若不包含当前月 需要手动push数据 // 默认以当前月数据为准 若不包含当前月 需要手动push数据
if (!data.includes(_now)) { if (!data.includes(_now)) {
...@@ -586,8 +597,12 @@ export default { ...@@ -586,8 +597,12 @@ export default {
this.statisticsTimer = null; this.statisticsTimer = null;
}, },
// 实时统计 // 实时统计
statisticsSum(value, prop) { statisticsSum(value, prop, row) {
this.clearStatisticsTimer(); this.clearStatisticsTimer();
const reg = /^(?!0\d)(?!0+$)(?!0*\.0*$)\d+(\.\d+)?$/;
if (reg.test(value)) {
row[prop] = add(0, value);
}
// 填写一秒后触发 // 填写一秒后触发
this.statisticsTimer = setTimeout(() => { this.statisticsTimer = setTimeout(() => {
const sum = this.sumHandler(this.dataForm.tableDataList, prop, this.hasTarget); const sum = this.sumHandler(this.dataForm.tableDataList, prop, this.hasTarget);
...@@ -613,7 +628,7 @@ export default { ...@@ -613,7 +628,7 @@ export default {
// 当前行源数据是否存在以推送工程量 // 当前行源数据是否存在以推送工程量
rowHasLastPush(index) { rowHasLastPush(index) {
const _tempRow = this.originTableDataList[index]; const _tempRow = this.originTableDataList[index];
return !parseFloat(_tempRow.quantities) return !parseFloat(_tempRow.quantities);
}, },
// 保存 // 保存
saveActualCost() { saveActualCost() {
...@@ -638,26 +653,46 @@ export default { ...@@ -638,26 +653,46 @@ export default {
recordDate: this.recordDate recordDate: this.recordDate
}; };
}); });
// 有差异数据 记录滚动条滚动位置
await this.getLastScrollTop();
const result = await updateFeedSummaryRowsApi(resultData); const result = await updateFeedSummaryRowsApi(resultData);
if (result.code == 200) { if (result.code == 200) {
this.$message.success("保存成功"); this.$message.success("保存成功");
await this.init(this.comProjectDetailInfo, this.selectActualCostTime); await this.init(this.comProjectDetailInfo, this.recordDate, true);
await this.$nextTick();
await this.editRegionToViewPort(); await this.editRegionToViewPort();
} }
} }
}); });
}, },
//获取竖向滚动条最后的位置
async getLastScrollTop() {
const table = document.querySelector(".custom-table .el-table__body-wrapper");
if (table) {
this.lastScrollTop = table.scrollTop;
}
},
// 推送工程用量 // 推送工程用量
pushProjectUse(row) { pushProjectUse(row) {
if (!row.id) return; if (!row.id) return;
// 打开推送推送弹窗 // 打开推送推送弹窗
const _temp = { ...this.pushProjectUseTemp, ...cloneDeep(row), projectDetailInfo: cloneDeep(this.projectDetailInfo) }; const _temp = {
...this.pushProjectUseTemp, ...{
id: row.id,
projectName: this.projectDetailInfo.projectName,
totalQuantities: row.totalQuantities,
pushQuantities: "",
ipmProjectCode: "",
ipmContractCode: "",
ipmBizCode: ""
}
};
this.pushProjectUseTemp = _temp; this.pushProjectUseTemp = _temp;
this.pushProjectUseDialog = true; this.pushProjectUseDialog = true;
}, },
// 推送工程用量弹窗关闭 // 推送工程用量弹窗关闭
dialogClose() { dialogClose() {
this.pushProjectUseTemp = {}; this.pushProjectUseTemp = this.$options.data.call(this).pushProjectUseTemp;
}, },
differentCompare() { differentCompare() {
const originData = this.originTableDataList; const originData = this.originTableDataList;
...@@ -666,8 +701,10 @@ export default { ...@@ -666,8 +701,10 @@ export default {
*/ */
let data = cloneDeep(this.dataForm.tableDataList); let data = cloneDeep(this.dataForm.tableDataList);
const different = data.filter((item, index) => { const different = data.filter((item, index) => {
if (index == 0) return false; if (index == 0 && this.hasTarget) return false;
const flag = editPropNames.some(prop => { const flag = editPropNames.some(prop => {
// 两个皆为无效值 返回false
if (!parseFloat(item[prop]) && !parseFloat(originData[index][prop])) return false;
return item[prop] != originData[index][prop]; return item[prop] != originData[index][prop];
}); });
return flag; return flag;
...@@ -675,7 +712,7 @@ export default { ...@@ -675,7 +712,7 @@ export default {
return cloneDeep(different); return cloneDeep(different);
}, },
// 编辑状态下 进行了其它操作 // 编辑状态下 进行了其它操作
resetEditStatus() { resetEditStatus(saveReset = false) {
// 当前需要编辑或者新增的成本年份 // 当前需要编辑或者新增的成本年份
const _selectActualCostTime = this.selectActualCostTime; const _selectActualCostTime = this.selectActualCostTime;
this.addActualCostEditStatus = false; this.addActualCostEditStatus = false;
...@@ -687,7 +724,7 @@ export default { ...@@ -687,7 +724,7 @@ export default {
if (!_selectActualCostTime) return; if (!_selectActualCostTime) return;
if (!this.originMonthList.includes(_selectActualCostTime) && _selectActualCostTime != this.getNowMonth()) { if (!this.originMonthList.includes(_selectActualCostTime) && _selectActualCostTime != this.getNowMonth()) {
const index = this.monthList.findIndex(item => item.value == _selectActualCostTime); const index = this.monthList.findIndex(item => item.value == _selectActualCostTime);
if (index != -1) { if (index != -1 && !saveReset) {
this.monthList.splice(index, 1); this.monthList.splice(index, 1);
this.recordDate = this.getNowMonth(); this.recordDate = this.getNowMonth();
} }
...@@ -722,10 +759,10 @@ export default { ...@@ -722,10 +759,10 @@ export default {
// 获取选中月数据 // 获取选中月数据
await this.getFeedSummaryList(params); await this.getFeedSummaryList(params);
// 将编辑区域移动到视口 // 将编辑区域移动到视口
await this.$nextTick();
await this.editRegionToViewPort(); await this.editRegionToViewPort();
}, },
async editRegionToViewPort() { async editRegionToViewPort() {
await this.$nextTick();
// 获取编辑列所处位置 // 获取编辑列所处位置
const container = document.querySelector(".el-table__body-wrapper"); const container = document.querySelector(".el-table__body-wrapper");
/** /**
...@@ -737,8 +774,9 @@ export default { ...@@ -737,8 +774,9 @@ export default {
container.scrollTo({ container.scrollTo({
behavior: "smooth", behavior: "smooth",
left, left,
top: 0 top: this.lastScrollTop
}); });
this.lastScrollTop = 0;
} }
}, },
cellClassName({ row, column, rowIndex, columnIndex }) { cellClassName({ row, column, rowIndex, columnIndex }) {
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
<div class="field-expenses-container"> <div class="field-expenses-container">
<div class="field-expenses-inner"> <div class="field-expenses-inner">
<div class="left-side-menu"> <div class="left-side-menu">
<project-side-menu ref="projectSideMenu" :menuTree="menuTreeList" :menuOptions="menuOptions" :unique-opened="false" <project-side-menu ref="projectSideMenu" :menuTree="menuTreeList" :menuOptions="menuOptions" :unique-opened="false" v-model="currentNodeValue"
v-model="currentNodeValue" @select="menuSelect"> @select="menuSelect">
<template slot="现场经费-1"> <template slot="现场经费-1">
<img src="@/assets/images/projectCostLedger/icon_cost_detail_6.svg" alt=""> <img src="@/assets/images/projectCostLedger/icon_cost_detail_6.svg" alt="">
<div class="project-sub-menu-title-text">现场经费</div> <div class="project-sub-menu-title-text">现场经费</div>
...@@ -174,7 +174,10 @@ export default { ...@@ -174,7 +174,10 @@ export default {
}, },
//计算集 //计算集
computed: { computed: {
// 是否是现场经费
isDefaultSumMenu() {
return this.currentNodeName == "现场经费";
}
}, },
//方法集 //方法集
methods: { methods: {
...@@ -203,12 +206,13 @@ export default { ...@@ -203,12 +206,13 @@ export default {
try { try {
await this.$nextTick(); await this.$nextTick();
const menus = this.$refs["projectSideMenu"].getResultMenuList(); const menus = this.$refs["projectSideMenu"].getResultMenuList();
const defaultCurrent = this.findMenuNode(menus, "现场经费"); const first = this.$refs["projectSideMenu"].getFirstLevelWithDeepId();
const defaultCurrent = this.findMenuNode(menus, "现场经费") ? this.findMenuNode(menus, "现场经费") : this.findMenuNode(menus, first, "nodeValue");
if (defaultCurrent) { if (defaultCurrent) {
this.currentNodeValue = defaultCurrent.nodeValue; this.currentNodeValue = defaultCurrent.nodeValue;
this.currentNodeName = defaultCurrent.nodeName; this.currentNodeName = defaultCurrent.nodeName;
const params = this.createRequestConditions(); const params = this.createRequestConditions();
await this.getFieldExpensesList(params); this.isDefaultSumMenu ? await this.getFieldExpensesList(params) : await this.getFieldExpensesOtherList(params);
} }
} catch (error) { } catch (error) {
console.log(error); console.log(error);
...@@ -223,7 +227,7 @@ export default { ...@@ -223,7 +227,7 @@ export default {
projectId, projectId,
cbStage cbStage
}; };
params["cbSubjectName"] = this.currentNodeValue; params["fileId"] = this.currentNodeValue;
// 判断当月是否存在于server返回month集合中 // 判断当月是否存在于server返回month集合中
const _now = this.getNowMonth(); const _now = this.getNowMonth();
if (this.includeNowMonth(_now)) { if (this.includeNowMonth(_now)) {
...@@ -243,6 +247,7 @@ export default { ...@@ -243,6 +247,7 @@ export default {
if (result) return result; if (result) return result;
} }
} }
return null;
}, },
async getFieldExpensesList(params = {}) { async getFieldExpensesList(params = {}) {
try { try {
...@@ -354,12 +359,8 @@ export default { ...@@ -354,12 +359,8 @@ export default {
const menuName = currentTemp.nodeName; const menuName = currentTemp.nodeName;
this.currentNodeName = menuName; this.currentNodeName = menuName;
// 请求数据列表 // 请求数据列表
const isDefault = menuName == "现场经费"; const params = this.createRequestConditions();
const params = isDefault ? this.createRequestConditions() : { if (this.isDefaultSumMenu) {
projectId: this.comProjectDetailInfo.projectId,
fileId: currentId
};
if (isDefault) {
this.getFieldExpensesList(params); this.getFieldExpensesList(params);
} else { } else {
this.getFieldExpensesOtherList(params); this.getFieldExpensesOtherList(params);
......
<template> <template>
<div class="project-side-menu-container"> <div class="project-side-menu-container">
<el-menu mode="vertical" class="project-side-menu-instance" :unique-opened="uniqueOpened" :default-active="createMenuIndex(comDefaultActive)" <transition name="fade" :appear="true" mode="out-in">
:default-openeds="comDefaultOpeneds" @select="menuSelect" @open="subMenuOpen" @close="subMenuClose" ref="customElMenu"> <el-menu v-if="tempMenuTree.length" mode="vertical" class="project-side-menu-instance" :unique-opened="uniqueOpened"
:default-active="createMenuIndex(comDefaultActive)" :default-openeds="comDefaultOpeneds" @select="menuSelect" @open="subMenuOpen"
@close="subMenuClose" ref="customElMenu">
<template v-for="(item, index) of tempMenuTree"> <template v-for="(item, index) of tempMenuTree">
<project-menu-item :menuItem="item" :key="`${item.nodeValue}-${item.level}`"> <project-menu-item :menuItem="item" :key="`${item.nodeValue}-${item.level}`">
<template :slot="`${item.nodeName}-${item.level}`" slot-scope="scope"> <template :slot="`${item.nodeName}-${item.level}`" slot-scope="scope">
...@@ -10,6 +12,7 @@ ...@@ -10,6 +12,7 @@
</project-menu-item> </project-menu-item>
</template> </template>
</el-menu> </el-menu>
</transition>
</div> </div>
</template> </template>
<script> <script>
...@@ -201,6 +204,9 @@ export default { ...@@ -201,6 +204,9 @@ export default {
await this.$nextTick(); await this.$nextTick();
this.openTargetAllSubMenu(this.comDefaultOpeneds); this.openTargetAllSubMenu(this.comDefaultOpeneds);
} }
} else {
this.tempMenuTree = [];
this.tempMenuOptions = this.$options.data.call(this).tempMenuOptions;
} }
}, },
mergeMenuOptions(options) { mergeMenuOptions(options) {
...@@ -275,12 +281,14 @@ export default { ...@@ -275,12 +281,14 @@ export default {
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
border-right: 1px solid #eeeeee;
background: #fff;
overflow: auto;
::v-deep .project-side-menu-instance { ::v-deep .project-side-menu-instance {
width: 100%; width: 100%;
height: 100%; border-right: unset;
border-right: 1px solid #eeeeee; background: unset;
overflow: auto;
/* 重置一级二级菜单 高度行高 */ /* 重置一级二级菜单 高度行高 */
.project-menu-item-container { .project-menu-item-container {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment