xm-3.0
630
README.md
@@ -4,34 +4,31 @@
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<strong>唛盟(mdp-lcode vue3 ):多功能、高效率、低代码(支持0代码) 前后端一体化、智能化的开发工具</strong>
|
||||
<strong>唛盟xm:涵盖项目规划、需求管理、开发迭代、版本控制、缺陷跟踪、测试管理、工时管理、效能分析等环
|
||||
节,实现项目全过程、全方位管理的一站式企业研发项目管理解决方案</strong>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a target="_blank" href="https://gitee.com/maimengcloud/mdp-lcode-ui-web">
|
||||
<img src='https://gitee.com/maimengcloud/mdp-lcode-ui-web/badge/star.svg?theme=gvp' alt='gitee star'/>
|
||||
<a target="_blank" href="https://gitee.com/maimengcloud/xm-ui-web">
|
||||
<img src='https://gitee.com/maimengcloud/xm-ui-web/badge/star.svg?theme=gvp' alt='gitee star'/>
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
👉 <a target="_blank" href="https://maimengcloud.com/lcode">https://maimengcloud.com </a> 👈
|
||||
👉 <a target="_blank" href="https://maimengcloud.com/xm/m1/">https://maimengcloud.com</a> 👈
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
## 快速导航
|
||||
## 快速导航
|
||||
|
||||
- [唛盟-后端开发底座](https://gitee.com/maimengcloud/mdp-core)
|
||||
- [前端组件](https://gitee.com/maimengcloud/mdp-lcode-ui-web)
|
||||
- [后端服务](https://gitee.com/maimengcloud/mdp-lcode-backend)
|
||||
- [体验环境](https://maimengcloud.com/lcode/)
|
||||
登陆界面上选择演示账号登陆或者直接扫码登陆,无须注册
|
||||
- 👉[教程]b站上搜素 [唛盟9哥教你撸前后端代码](https://www.bilibili.com/video/BV111421S72r/?spm_id_from=333.337.search-card.all.click&vd_source=93be23d03863773d50b81112985b9237)
|
||||
- [前端组件](https://gitee.com/maimengcloud/xm-ui-web)
|
||||
- [后端服务](https://gitee.com/maimengcloud/xm-backend)
|
||||
- [体验环境](https://maimengcloud.com/xm/m1/)
|
||||
登陆界面上选择演示账号登陆(账号密码:demo-branch-01 888888)或者直接扫码登陆,无须注册
|
||||
- 相关教程b站上搜素[唛盟9哥教你撸前后端代码](https://www.bilibili.com/video/BV111421S72r/?spm_id_from=333.337.search-card.all.click&vd_source=93be23d03863773d50b81112985b9237)
|
||||
|
||||
|
||||
## 📢 简介[唛盟低代码开发平台mdp-lcode](/)
|
||||
|
||||
唛盟低代码开发平台简称唛盟或者mdp. 👉[唛盟-总体介绍](https://www.bilibili.com/video/BV111421S72r/?spm_id_from=333.337.search-card.all.click&vd_source=93be23d03863773d50b81112985b9237)
|
||||
唛盟旨在为企业开发业务系统提供一整套解决方案,唛盟具有高效率、低代码、支持0代码、功能丰富等特点。企业可以在唛盟工程之上,加入更多其它业务功能;也可以以唛盟作为模板,创建新的工程,用于开发其它业务。使用唛盟构建应用,您不用考虑多租户、登录、统一认证中心、权限、菜单管理、系统管理、公共组件、公共api、代码冗余、数据字典、图片库、文件库、智能表单、工作流、微服务互相调用、全局跟踪定位bug、多主键crud,复杂sql查询等各种问题,这些问题的解决方案都作为扩展功能内置唛盟工程中了。
|
||||
## 📢 简介[唛盟xm](/)
|
||||
唛盟企业级研发管理系统简称唛盟xm,属于唛盟生态的专业子系统之一,以研发管理为核心,涵盖项目规划、需求管理、开发迭代、版本控制、缺陷跟踪、测试管理、工时管理、效能分析等环节,实现全过程、全方位的研发管理。通过该系统,企业能够优化研发流程,提高研发效率,降低研发成本,提高市场竞争力。
|
||||
💪给你一个使用唛盟的理由:代码大量减少、开发so easy、前后端MIT协议、全部开源、永久免费
|
||||
|
||||
## 📢 唛盟生态
|
||||
@@ -78,7 +75,7 @@
|
||||
|
||||
| 框架 | 说明 | 版本 |
|
||||
|----------------------------------------------------------------------|------------------|--------|
|
||||
| spring boot | spring boot 框架 | 2.4.1 |
|
||||
| spring boot | spring boot 框架 | 2.6.11 |
|
||||
| mybatis plus | 数据库操作框架 | 3.5.3.1 |
|
||||
| spring security | 安全框架 | 2.1.7 |
|
||||
| jsqlparse | sql解析引擎 | 4.7+ |
|
||||
@@ -110,7 +107,6 @@
|
||||
| Prettier | 代码格式化 |
|
||||
| ESLint | 脚本代码检查 |
|
||||
| DotENV | env 文件高亮 |
|
||||
| [ruoyi-vue-pro](https://gitee.com/zhijiantianya/ruoyi-vue-pro)|前端流程ui基于若依修改
|
||||
|
||||
|
||||
|
||||
@@ -120,513 +116,176 @@
|
||||
| idea | java 开发工具 社区版、企业版都可 |
|
||||
|
||||
|
||||
## 😭 日常开发中,您是否有以下痛点?
|
||||
|
||||
- **团队中缺乏企业级前后端分离的开发底座**,需要在各种框架中进行摸索、整合。
|
||||
- ai时代,开发工具如何去支持未来的软件开发?
|
||||
- 重复造轮子现象严重、浪费人力、对开发者经验要求过高。
|
||||
- 缺乏统一的开发模式,缺乏公共组件的抽取和共享机制,导致业务代码混乱不堪、代码臃肿、bug多、维护困难
|
||||
- 缺乏统一的足够灵活的权限管理机制,开发人员不得不写一堆的权限代码混入业务代码中,前端权限、后端权限控制混乱不堪
|
||||
- 缺乏统一的能够覆盖前后端的、满足前后端分离的代码生成器,代码模板无法按企业现状进行重新编辑、修改
|
||||
- 缺乏统一的编程规范,或者具有书面编程规范,难以贯彻落实到开发中,代码还是五花八门
|
||||
- 缺乏统一的元数据(数据字典)管理机制,前后的数据共享调用困难,下拉列表数据混乱不堪
|
||||
- 缺乏统一的流程管理机制,要想进行流程类业务开发非常困难
|
||||
- 缺乏统一的国际化机制,国际化实施困难,不得不针对各种语言发布多个版本,无法解决后端国际化、前端国际化等问题
|
||||
- 缺乏统一的微服务、分布式系统整合机制,微服务互相调用、微服务的权限管理困难
|
||||
- 缺乏统一的认证中心,单点登录实施困难
|
||||
- 缺乏统一的支付整合机制,接入微信、支付宝、paypal等困难
|
||||
- 缺乏项目管理工具,项目计划、任务委派、质量管理、需求管理、持续集成等完全没概念
|
||||
- **让 唛盟-mdp 来帮你解决这些痛点吧!然而,这些只是 唛盟-mdp 解决的最基础的功能。**
|
||||
|
||||
## 😁 为什么要使用唛盟产品
|
||||
|
||||
- 唛盟所有子系统从前端到后端提供ai支持能力
|
||||
1. 前端每个字段可以调起ai指令、el表达式
|
||||
2. 后端每个接口可以支持识别ai指令、el表达式
|
||||
3. 后端支持接入大模型
|
||||
4. 具有根据企业数字资产进行ai自训练能力
|
||||
|
||||
- 完全开源、永久免费的企业级开发底座
|
||||
1. 使用mdp能够带来开发效率的大幅提升,代码行数大幅减少,质量提升明显
|
||||
2. 使用mdp能够大幅度降低对开发人员的经验要求,大幅度降低人力成本
|
||||
3. mdp对各种开源组件进行了融合改进,提供了针对企业开发中各种问题的最佳解决方案
|
||||
4. 企业使用一套开源软件即同时拥有前端开发框架及后端开发框架
|
||||
|
||||
- 统一的开发模式
|
||||
1. 前后端分离
|
||||
2. 前后端都分别进行了技术组件、业务组件的抽取、共享,企业可以进行再提炼、抽象,形成更多的公共组件,对后续开发形成强力的支撑作用
|
||||
|
||||
- 足够灵活的权限管理机制
|
||||
1. 前端提供统一的按钮级别的权限判断接口、提供路由菜单的权限控制机制
|
||||
2. 后端实现api接口的自动注册、自动审核
|
||||
3. 基于岗位-部门-角色-菜单及按钮-后端api-人员 6要素的权限管理机制,可以0编程实现绝大多数的权限需求
|
||||
|
||||
- 基于领域驱动设计(DDD)的框架及代码生成器
|
||||
1. 代码生成器覆盖前端、后端,支持任意时刻的重新生成,支持命令行、开发工具插件、在线三种方式生成代码,生成的代码可以0编程使用
|
||||
2. 代码生成器代码模板可以按企业现状进行修改、满足不断发展、持续改进的需求
|
||||
3. 支持多个表一次性生成,也就是可以一次性生成几十到几百张表的增删改查功能,而开发人员仅需要填写表名即可完成
|
||||
|
||||
- 提供完整的编程规范说明
|
||||
1. mdp的框架提供了完备的接口说明、组件说明、组件使用场景等
|
||||
2. mdp维护团队提供在线支持,及时解答、解决开发者使用过程中的问题
|
||||
|
||||
- 提供强大的元数据(数据字典)管理机制
|
||||
1. 内置了元数据管理模块,并实现了元数据的分布式缓存、客户端缓存、元数据分发、缓存清理等
|
||||
2. 开发者在客户端、任意微服务中、任意单体应用中可以快速获取元数据
|
||||
3. 元数据的调用效率等同于调用本地map缓存,几乎可以忽略使用元数据的性能开销问题
|
||||
|
||||
- 整合了最新版本的强大的flowable工作流引擎
|
||||
1. 基于mdp框架重新开发了流程中心、任务中心、流程的发布、上下架等功能
|
||||
2. 提供分布式环境下的流程调用、流程整合问题的解决方案
|
||||
3. 提供vue3版本在线流程设计器,并整合了mdp的权限机制
|
||||
4. 整合了mdp的智能表单
|
||||
5. 整合了mdp的数据字典,通过配置即可实现大部分业务场景,真正做到流程设计、部署、运行0耗时,0延迟。
|
||||
4. 任务的提交支持几乎能想到的各种方式:转办、委办、主办、前加签、后加签、减签、发起人处理、驳回任意节点、审批同意、审批不同意但流程继续、拒绝终止流程等,同时提供框架的提交方式可扩展性,让你轻松应对各种变态需求。
|
||||
5. 会签支持:会签、或签、过半通过、一票否决等等
|
||||
6. 任务分配到人十来种策略支持并提供扩展接口:按岗位、按部门、按组、按标签、按指定人员、发起人、上一步执行人、上一步执行人临时指定、发起流程时统一指定、转主办、转监控、按高级自定义查询条件、
|
||||
7. 整合了mdp的消息发送机制,轻松发送流程消息到im、站内信、公众号、短信
|
||||
8. 整合mdp事件模型,为将来ai调用流程等创新场景提供底层基础
|
||||
9. 提供业务模块内嵌页面发起流程的组件和统一的方式,开发几乎可以无视工作流相关的接入工时。
|
||||
10. 整合mdp附件管理
|
||||
|
||||
|
||||
- 提供强大的国际化解决方案
|
||||
1. 前后端均支持分别进行国际化
|
||||
2. 多语言的支持与业务代码完全解耦,彻底解决硬编码进行语言切换的问题
|
||||
|
||||
- 整合了强大的微服务框架
|
||||
1. mdp平台任意组件均同时支持微服务环境、单体应用环境运行,开发人员开发的时候可以以单体应用的方式开发,然后以微服务方式发布到生产、测试环境
|
||||
2. 提供微服务的治理
|
||||
|
||||
- 强大的DAO层
|
||||
1. 支持基于xml文件的sql编写
|
||||
2. 支持无xml方式的数据访问
|
||||
3. 支持多主键(对mybatis plus进行升级,解决了多主键、多表联合查询等问题)
|
||||
4. 支持多数据源,通过备注实现数据源切换
|
||||
5. 支持前端构建任意复杂的查询条件并提供对应的最佳实践,支持前端输入框输入>,=,*,$IS NULL,$IN,$NOT IN等运算操作符,支持前端通过 or and 连接符构建任意复杂的条件表达式
|
||||
|
||||
- 强大的web ui
|
||||
1. 提供好用好看的ui组件库
|
||||
2. 提供页面高级查询功能、可以组装任意复杂的查询条件
|
||||
3. 提供针对元数据(数据字典)的引用、针对任意表的引用的组件库
|
||||
4. 提供导入、导出等基础功能
|
||||
5. 提供按钮权限判断接口、
|
||||
6. 提供动态菜单功能
|
||||
|
||||
- 提供自定义表单解决方案,具有0代码0延时发布一个新功能的能力
|
||||
1. 自定义表单设计
|
||||
2. 表单展现
|
||||
3. 表单数据管理
|
||||
4. 自定义表单与工作流整合使用
|
||||
5. 自定义表单发布成普通菜单
|
||||
|
||||
- 整合了微信支付、支付宝支付、paypal支付
|
||||
1. 提供支付、订单、支付通知底层框架,可以快速整合各种支付功能
|
||||
2. 整合了微信支付功能,进行配置文件更新即可使用
|
||||
3. 整合了支付宝支付功能,进行配置文件更新即可使用
|
||||
4. 整合了paypal支付,进行配置文件更新即可使用
|
||||
|
||||
- 整合了oauth2.0框架
|
||||
1. 提供oauth2.0的整体框架,构建统一认证中心、单点登录等不再是难事
|
||||
2. 整合了微信、支付宝、手机验证码、账户密码等登录方式
|
||||
|
||||
## 💪 内置功能、界面展示
|
||||
|
||||
### 组织管理
|
||||
|功能 |描述|
|
||||
|-------------------------------|--------------------------|
|
||||
|机构管理 | 企业信息维护、管理员维护、账户信息维护、企业产品维护、|
|
||||
|用户管理 | 用户的crud、分配岗位、分配部门、重置密码、邀请|
|
||||
|部门管理 | 部门curd、分配岗位到部门、查看部门用户|
|
||||
|公司管理 | 公司curd(超级管理员使用)|
|
||||
|岗位管理 | 岗位curd、分配角色到岗位、岗位人员查看|
|
||||
|注销审核 | 审核用户的注销申请|
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
### 个人中心
|
||||
|功能 |描述|
|
||||
|-------------------------------|--------------------------|
|
||||
|个人信息 | 基本信息、邮箱、手机、企业绑定、微信绑定等|
|
||||
|我的消息 | 接收个人私信、公告等|
|
||||
|登录日志 | 查询我的登录日志 |
|
||||
|
||||

|
||||
### 角色权限
|
||||
|功能 |描述|
|
||||
|-------------------------------|--------------------------|
|
||||
|角色管理 | 角色crud、分配菜单、分配权限|
|
||||
|权限定义 | 权限crud|
|
||||
|菜单管理 | 菜单(按钮)crud、分配菜单(按钮)给角色、|
|
||||
|模块管理 | 模块crud|
|
||||
|已开模块 | 查看企业(个人)已开通的模块|
|
||||
|
||||

|
||||

|
||||
|
||||
### 平台管理
|
||||
|功能 |描述|
|
||||
|-------------------------------|--------------------------|
|
||||
|平台配置 | 配置平台的信息|
|
||||
|个人认证审核 | 审核个人的实名认证请求|
|
||||
|企业认证审核 | 审核企业的实名认证请求|
|
||||
|
||||

|
||||
|
||||
### 元数据管理
|
||||
|功能 |描述|
|
||||
|-------------------------------|--------------------------|
|
||||
|字典管理 | 数据字典的crud|
|
||||
|列表维护 | 下拉列表数据项的crud|
|
||||
|参数定义 | 公共系统参数的crud|
|
||||
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
### 数据模型
|
||||
|功能 |描述|
|
||||
|-------------------------------|--------------------------|
|
||||
|模型中心 | 模型的crud|
|
||||
|表格结构 | 表结构预览、表结构修改、表的字段维护等|
|
||||
|表格数据 | 表的业务数据crud等|
|
||||
|数据集市 | 可以快速构造查询sql,提供给外部接口、智能表单、数据分析等使用|
|
||||
|创建数据集 | 数据集的设计、保存、预览数据等|
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
### 智能表单
|
||||
支持mdp-ui组件的拖拉拽,支持表单0编码0耗时发布形成一个新的功能
|
||||
|
||||
|功能 |描述|
|
||||
|-------------------------------|--------------------------|
|
||||
|表单中心 |表单列表,权限管理,数据查阅等 |
|
||||
|创建表单 | 表单设计、预览|
|
||||
|
||||

|
||||
|
||||
### 内容管理
|
||||
|功能 |描述|
|
||||
|-------------------------------|--------------------------|
|
||||
|附件库 | 附件上传、预览、权限配置等|
|
||||
|图片库 | 图片上传、预览、删除等|
|
||||
|图标库 | 图标的预览、选用等|
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### 订单管理
|
||||
|功能 |描述|
|
||||
|-------------------------------|--------------------------|
|
||||
|我的订单 | 订单查看、管理、打折促销等|
|
||||
|购买产品 | 下单购买应用|
|
||||
|增购人数 | 增加企业人数|
|
||||
|续费 | 到期续费|
|
||||
|
||||

|
||||
|
||||
### 第三方管理
|
||||
|功能 |描述|
|
||||
|-------------------------------|--------------------------|
|
||||
|邀请管理 | 查询、管理我发起的邀请|
|
||||
|我邀请的用户 | 查询我邀请的用户列表|
|
||||
|第三方用户查询 | 查询第三方账户信息 |
|
||||
|
||||
|
||||
### 流程模型
|
||||
|功能 |描述|
|
||||
|-------------------------------|--------------------------|
|
||||
|流程编辑器 | 在线流程编辑器|
|
||||
|模型发布 | 流程模型发布|
|
||||
|模型设置 | 设置流程与智能表单的关联、模型的启动条件、审批人、权限等|
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
### 审批中心
|
||||
|功能 |描述|
|
||||
|-------------------------------|--------------------------|
|
||||
|待执行 | 我的待执行任务查询、任务执行|
|
||||
|日历任务 | 我的待执行任务查询、任务执行|
|
||||
|发起流程 | 发起流程|
|
||||
## 😭 日常项目管理中,您是否有以下痛点?
|
||||
### 需求管控困难
|
||||
- 需求不明确:客户提出一些模糊的需求,这可能导致开发团队对需求的理解存在偏差。
|
||||
- 信息分散、杂乱:需求可能散落在多个地方,如邮件、Excel表格、即时通讯工具、不同的项目组等无法进行统一管理。
|
||||
- 需求追溯困难:提出者、评审者、实施人等不明确,导致责任不清、分工不明等问题产生。
|
||||
- 需求与开发脱节:无法实时跟踪需求完成情况。无法实时定位需求进度落后原因,进而无法做出补救措施。
|
||||
- 需求与测试不匹配:需求文档与测试用例不匹配导致测试工作无法顺利进行
|
||||
- 需求变更频发:频繁变更需求,给开发团队带来很大的困扰。
|
||||
|
||||
### 任务管理困难
|
||||
- 任务分配不明确:任务通过口头或邮件形式进行分配,这可能导致任务责任不明确和任务重叠。
|
||||
- 任务发布、沟通困难:由于涉及的成员和部门众多,信息同步不及时,很容易导致项目协作混乱。
|
||||
- 任务进度把控难:缺乏有效的工具来跟踪任务进度,团队成员很难准确把握项目的整体完成情况,也无法针对性地进行调整。
|
||||
- 任务风险管理不充分:常常忽视任务风险管理,导致项目面临较大的风险。
|
||||
- 工时统计困难:手动记录工时不仅容易出错,而且难以统计和分析,这不仅影响团队成员的个人成果统计,也影响团队之间的凝聚力和协作效果。
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
### 质量管理困难
|
||||
- 质量标准不明确:缺乏明确的质量标准和规范,导致团队成员对质量要求的理解存在差异,从而影响软件质量。
|
||||
- 质量保证不到位:导致软件存在缺陷和漏洞,影响用户体验和产品可靠性。
|
||||
- 测试不全面:缺乏缺陷登记跟踪工具、缺乏测试用例管理工具,导致一些潜在问题未被发现和解决,从而影响软件质量。
|
||||
- 质量管理与开发流程不融合:质量管理与开发流程相互分离,导致质量管理与开发效率相互影响,难以实现高效的软件开发。
|
||||
|
||||
### 审批监控
|
||||
|功能 |描述|
|
||||
|-------------------------------|--------------------------|
|
||||
|我发起的流程 | 查询我发起的流程|
|
||||
|我监控的流程 | 查询我监控的流程、催办|
|
||||
|我参与的流程 | 查询我参与过的流程|
|
||||
### 缺乏协作&沟通
|
||||
- 沟通渠道不统一:在开发团队中,不同的成员可能有不同的沟通渠道,导致信息分散,难以统一管理。
|
||||
- 沟通不够及时:在开发过程中,有时沟通不够及时,导致一些重要信息滞后的处理,影响了项目进度。
|
||||
- 沟通不够清晰:由于技术术语或背景知识的不同,团队成员之间的沟通有时不够清晰,导致理解上的偏差。
|
||||
- 沟通缺乏反馈机制:在沟通中,有时缺乏反馈机制,导致对问题的处理不够及时和有效。
|
||||
|
||||

|
||||
### 缺乏效能分析
|
||||
- 缺乏组织级、项目级、产品级、团队级、个人级、迭代级等不同组织级别的效能分析:企业在长期项目实施过程中,未构建起从组织级到个人级的效能分析体系,无法全面掌握企业的项目运作全貌,进而无法有效进行资源调配,利益最大化。
|
||||
- 缺乏对不同职能部门的多维度的效能分析
|
||||
- 缺乏风险预警、风险分析
|
||||
- 项目报告不全面、不准确
|
||||
- 质量报告不全面、不准确
|
||||
- 进度计划汇总、分解困难
|
||||
|
||||
### 低代码
|
||||
|功能 |描述|
|
||||
|-------------------------------|--------------------------|
|
||||
|代码生成器 | 在线生成crud的前端页面代码(表单、表格、api),后端代码(控制层、服务层、dao层代码),前后端0修改即可正常运行 |
|
||||
## 解决之道
|
||||

|
||||
|
||||
### 界面风格切换
|
||||
### 系统概况
|
||||

|
||||
|
||||

|
||||
### 系统特点
|
||||

|
||||
|
||||

|
||||
### 系统功能
|
||||

|
||||
|
||||

|
||||
### 技术架构
|
||||

|
||||
|
||||
## ⚙ 组件库[mdp-ui](/src/components/mdp-ui)
|
||||
|
||||
mdp封装了几十个ui组件,使用mdp-ui与不使用mdp-ui的区别:写100行代码还是写1行代码的区别,代码量的减少立竿见影
|
||||
- [mdp-ui](/src/components/mdp-ui)
|
||||
mdp的核心组件,该组件库为纯前端页面组件,无须配置任何后端api接口即可正确运行
|
||||
- [mdp-ui-ext](/src/components/mdp-ui-ext)
|
||||
基于mdp-ui扩展的带有对接后台api业务加载能力的业务组件
|
||||
### 应用架构
|
||||

|
||||
|
||||
>⚠️注意:先行体验一把[mdp-ui组件效果预览](https://maimengcloud.com/lcode/#/mdp/lcode/index)
|
||||
|
||||
### 非唛盟的子系统如何快速整合mdp-ui组件库
|
||||
>找到[main.ts](/src/main.ts) 添加下面代码
|
||||
```js
|
||||
### 项目总体管理
|
||||

|
||||
|
||||
//mdp-ui 基础组件
|
||||
import MdpComponents from '@/components/mdp-ui/index.js'
|
||||
//mdp-ui-ext拓展的组件
|
||||
import MdpUiExtComponents from '@/components/mdp-ui-ext/index.js'
|
||||
//唛盟公共api
|
||||
import MdpPubApi from "@/api/mdp_pub";
|
||||
|
||||
const app = createApp(App)
|
||||
### 需求管理
|
||||

|
||||
|
||||
app.use(MdpComponents)
|
||||
app.use(MdpUiExtComponents)
|
||||
app.config.globalProperties.$mdp=MdpPubApi
|
||||
|
||||
```
|
||||
### 项目计划
|
||||

|
||||
|
||||
### [mdp-dialog](/src/components/mdp-ui/mdp-dialog)
|
||||
弹框,可以把任意页面装配成弹框,无须定义多余的变量及函数
|
||||
- 相对于el-dialog来说,要使用弹窗,事情还真不少。需要定义visible变量,定义showDialog,closeDialog两个函数,最关键一点是如果要父页面传递参数到窗口内组件,还得在父页面定义一个变量,通过props属性传递。相当麻烦。如果某个功能弹窗特别多,会有一堆的控制弹窗的变量及函数,非常恶心。mdp-dialog则完全解决上述问题。
|
||||
|
||||
### [mdp-table](/src/components/mdp-ui/mdp-table)
|
||||
表格,内置了增、删、改、查、高级查询、重置查询、导出、列配置、分页、批量编辑等功能、内置了对按钮权限的控制机制
|
||||
功能非常强大,懂的都懂。
|
||||
### 质量管理
|
||||

|
||||
|
||||
- 综合管理
|
||||

|
||||
- 可编辑表格
|
||||

|
||||
- 可编辑-树状表格
|
||||

|
||||
|
||||
### [mdp-select](/src/components/mdp-ui/mdp-select)
|
||||
下拉列表,支持对数据字典、元数据的引用,支持对任意小表表格数据的引用,支持参数化加载后台数据,对后台加载的数据进行缓存
|
||||

|
||||
### 迭代管理
|
||||

|
||||
|
||||
### [mdp-select-table](/src/components/mdp-ui/mdp-select-table)
|
||||
超大表格下拉列表,与mdp-select相比,该组件具有分页查询功能
|
||||

|
||||
|
||||
### [mdp-select-user](/src/components/mdp-ui-ext/mdp-select-user)
|
||||
用户选择下拉列表,与mdp-select-table组件类似,仅仅针对用户的头像做了特殊处理
|
||||

|
||||
### 效能分析
|
||||

|
||||
|
||||
### [mdp-input](/src/components/mdp-ui/mdp-input)
|
||||
输入框
|
||||
## 💪 功能展示
|
||||
### 项目立项
|
||||

|
||||
|
||||
### [mdp-date](/src/components/mdp-ui/mdp-date)
|
||||
日期
|
||||
|
||||
### [mdp-date-range](/src/components/mdp-ui/mdp-date-range)
|
||||
区间日期
|
||||
### 项目总体
|
||||

|
||||
|
||||
### [mdp-number](/src/components/mdp-ui/mdp-number)
|
||||
数字输入
|
||||
|
||||
### [mdp-hi-query](/src/components/mdp-ui/mdp-hi-query)
|
||||
高级查询,可以由用户自定义任意复杂的查询条件
|
||||

|
||||
### 组织架构
|
||||

|
||||
|
||||
### [mdp-table-configs](/src/components/mdp-ui/mdp-table-configs)
|
||||
表格配置,用于控制表格的列显示与否
|
||||

|
||||
|
||||
### [mdp-transfer](/src/components/mdp-ui/mdp-transfer)
|
||||
穿梭框
|
||||
### 项目报告
|
||||

|
||||
|
||||
### [mdp-cate-tree](/src/components/mdp-ui-ext/mdp-cate-tree)
|
||||
文档、文章目录树
|
||||
|
||||
### [mdp-expand](/src/components/mdp-ui-ext/mdp-expand)
|
||||
智能表单相关组件
|
||||
### 需求管理
|
||||

|
||||
|
||||
### [mdp-ext-infos](/src/components/mdp-ui-ext/mdp-ext-infos)
|
||||
自动扩展字段信息
|
||||
|
||||
### 用户故事
|
||||

|
||||
|
||||
### [mdp-image](/src/components/mdp-ui-ext/mdp-image)
|
||||
图片库,图片的增删改查、上传、下载
|
||||
|
||||
### [mdp-select-image](/src/components/mdp-ui-ext/mdp-select-image)
|
||||
图片选择器,支持图片的上传下载、上传后的统一管理、共享
|
||||
### 项目计划
|
||||

|
||||
|
||||
### [mdp-select-dept](/src/components/mdp-ui-ext/mdp-select-dept)
|
||||
部门选择,支持树状机构,异步加载,支持分页查询,任意大数据量
|
||||
|
||||
### [mdp-select-att](/src/components/mdp-ui-ext/mdp-select-att)
|
||||
附件库,支持附件的上传下载、上传后的统一管理、共享
|
||||
### 项目计划-任务
|
||||

|
||||
|
||||
### [mdp-select-cate](/src/components/mdp-ui-ext/mdp-select-cate)
|
||||
文档、文章目录树选择器
|
||||
|
||||
### [mdp-select-tag](/src/components/mdp-ui-ext/mdp-select-tag)
|
||||
标签库,支持标签的统一管理、共享
|
||||
### 迭代概览
|
||||

|
||||
|
||||
|
||||
### [mdp-meta-item](/src/components/mdp-ui-ext/[mdp-meta-item)
|
||||
元数据管理库、支持元数据的crud
|
||||
### 迭代维护
|
||||

|
||||
|
||||
### [mdp-meta-option](/src/components/mdp-ui-ext/mdp-meta-option)
|
||||
元数据管理库-列表数据组件、支持列表数据的crud
|
||||
|
||||
### [mdp-rich-text](/src/components/mdp-ui-ext/mdp-rich-text)
|
||||
富文本编辑器,整合了mdp-select-image作为插件
|
||||
### 测试管理
|
||||

|
||||
|
||||
## 🔃 api
|
||||
- [api](/src/api/)
|
||||
业务api,哪里用到哪里就单独引入
|
||||
### [api/mdp_pub/index.js](/src/api/mdp_pub/index.js)
|
||||
公共api总入口,注册到vue全局函数中,可以在页面中任意地方直接使用,公共api总入口,如需要添加公共api,请在此文件添加
|
||||
### [mdp_api_base.js](/src/api/mdp_pub/mdp_api_base.js)
|
||||
为mdp框架核心的与后端交互的api,自动注册为全局公共函数,可通过$mdp.xxx调用,可改,但不要新增,删除任何一个api.
|
||||
### [mdp_api_ext.js](/src/api/mdp_pub/mdp_api_ext.js)
|
||||
为mdp扩展的组件与后端交互的api,自动注册为全局公共函数,可通过$mdp.xxx调用,可改,但不要新增,删除任何一个api.
|
||||
### [mdp_api_biz.js](/src/api/mdp_pub/mdp_api_biz.js)
|
||||
为mdp扩展的组件与后端交互的api,自动注册为全局公共函数,可通过$mdp.xxx调用,可改,可新增必要的api.
|
||||
|
||||
### [mdp_config.js](/src/api/mdp_pub/mdp_config.js)
|
||||
前端工程的一些公共配置项,主要配置每一类api对接哪个后端微服务
|
||||
根据不同的环境,需要修改部分内容。mdp_config配置项已与vue3工程公共配置打通,vue3依赖于VIET_*的全局配置项,因此,vue3及更高版本之后应该以VITE的配置为准,详细查阅 [env.d.ts](/types/env.d.ts)
|
||||
### 测试报告
|
||||

|
||||
|
||||
```js
|
||||
### 缺陷管理
|
||||

|
||||
|
||||
# 固定网址
|
||||
VITE_FIXED_DOMAIN=https://www.maimengcloud.com
|
||||
### 财务费用
|
||||

|
||||
|
||||
# 开源项目地址
|
||||
VITE_OPEN_SOURCE_LINK=https://gitee.com/qingqinkj218/collections/375320
|
||||
### 驾驶舱
|
||||

|
||||
|
||||
# 微信开放平台 appid
|
||||
VITE_WXOPEN_APPID=wx2671d5db8346b6fc
|
||||
### 效能分析
|
||||

|
||||
|
||||
#
|
||||
# 说明: VITE_CTX_# 为定义唛盟各个子系统的context;
|
||||
# context指向子系统的微服务名称,spring.application.name
|
||||
#
|
||||
# 1. 用于前端请求路径前缀映射,
|
||||
# 前端页面一般部署在 ./{VITE_CONTEXT}/{VITE_UI_VERSION?}
|
||||
#
|
||||
# 2. api导航到对应子系统等
|
||||
# api一般按以下格式规范组装 ./{VITE_API_BASE_PATH}/{VITE_API_VERSION}/{VITE_CONTEXT}
|
||||
#
|
||||
### 燃尽图
|
||||

|
||||
|
||||
# 登录相关,如果后端启用oauth2,则返回 oauth2client ,如果后端不启用oauth2,后端账户使用mdp-lcode服务,则返回 lcode ,如果使用mdp-sys提供服务,则返回sys
|
||||
VITE_CTX_LOGIN=oauth2client
|
||||
### 每日工作项分布
|
||||

|
||||
|
||||
# 项目管理子系统
|
||||
VITE_CTX_XM=xm
|
||||
### 任务年龄分布
|
||||

|
||||
|
||||
# 工作流子系统,由于flowable启动限制,目前不支持jar集成到lcode,需要单独部署
|
||||
VITE_CTX_WF=workflow
|
||||
### 任务排行棒
|
||||

|
||||
|
||||
# 低代码子系统
|
||||
VITE_CTX_LCODE=lcode
|
||||
### 测试用例规划分析
|
||||

|
||||
|
||||
# 内容管理子系统
|
||||
VITE_CTX_ARC=arc
|
||||
## 客户端展示
|
||||
### 小程序
|
||||

|
||||
|
||||
# 数据模型 由lcode接管
|
||||
VITE_CTX_DM=lcode
|
||||
### 审批管理
|
||||

|
||||
|
||||
# 协同办公
|
||||
VITE_CTX_OA=oa
|
||||
|
||||
# 系统管理,目前由lcode接管
|
||||
VITE_CTX_SYS=lcode
|
||||
|
||||
# 智能表单,目前由lcode接管
|
||||
VITE_CTX_FORM=lcode
|
||||
|
||||
# 商城-面向消费用户端
|
||||
VITE_CTX_MALL=mall
|
||||
|
||||
# 商城管理端
|
||||
VITE_CTX_MALLM=mallm
|
||||
|
||||
# 即时通讯
|
||||
VITE_CTX_IM=im
|
||||
|
||||
# 短信
|
||||
VITE_CTX_SMS=sms
|
||||
|
||||
# 唛盟内置的应用购买模块订单 目前由lcode接管
|
||||
VITE_CTX_MO=lcode
|
||||
|
||||
# 众包 目前由xm接管
|
||||
VITE_CTX_CROWD=xm
|
||||
|
||||
# 第三方集成系统
|
||||
VITE_CTX_TPA=tpa
|
||||
```
|
||||
|
||||
|
||||
#### api的调用方法
|
||||
```html
|
||||
<el-button @click="$mdp.xxxApi()"/>
|
||||
```
|
||||
```js
|
||||
//选项式
|
||||
this.$mdp.xxxApi()
|
||||
|
||||
//组合式 由于没有this,需要在顶部引入proxy
|
||||
const {proxy}: any = getCurrentInstance()
|
||||
proxy.$mdp.xxxApi()
|
||||
```
|
||||
|
||||
- [login](/src/api/login/index.ts.ts)
|
||||
登录相关api
|
||||
|
||||
## 🔃 指令
|
||||
- [v-adaptive](./src/components/mdp-ui/directive/adaptive.ts)
|
||||
让表格、div等自动适应,底部始终保持距离视窗底部一定距离(默认 30px)
|
||||
|
||||
```html
|
||||
<el-table v-adaptive="{bottomOffset:30}"/>
|
||||
|
||||
<el-table v-adaptive/>
|
||||
```
|
||||
### 测试管理
|
||||

|
||||
|
||||
|
||||
## 💻 样例项目
|
||||
|
||||
- [低代码平台] (https://maimengcloud.com/lcode/)
|
||||
- [系统管理] (https://maimengcloud.com/sys)
|
||||
- [低代码平台] (https://maimengcloud.com/lcode/)
|
||||
- [协同办公] (https://maimengcloud.com/oa)
|
||||
- [项目管理] (https://maimengcloud.com/xm)
|
||||
- [流程管理] (https://maimengcloud.com/wf)
|
||||
- [项目管理] (https://maimengcloud.com/xm)
|
||||
|
||||
## ⚙ 快速开始
|
||||
|
||||
@@ -649,14 +308,11 @@ pnpm install 包 // 安装依赖
|
||||
|
||||
### 前序准备
|
||||
|
||||
- 当前项目属于网页版前端ui项目,后端代码请移步到 [mdp-lcode-backend](https://gitee.com/maimengcloud/mdp-lcode-backend)
|
||||
|
||||
- 代码生成器下载 [mdp-code-generator](https://gitee.com/maimengcloud/mdp-code-generator) 也可以在低代码平台在线生成
|
||||
|
||||
- 当前项目属于网页版前端ui项目,后端代码请移步到 [xm-backend](https://gitee.com/maimengcloud/xm-backend)
|
||||
### 开发
|
||||
```bash
|
||||
# 克隆项目
|
||||
git clone https://gitee.com/maimengcloud/mdp-lcode-ui-web.git
|
||||
git clone https://gitee.com/maimengcloud/xm-ui-web.git
|
||||
|
||||
# 安装依赖
|
||||
pnpm install
|
||||
@@ -664,7 +320,7 @@ pnpm install
|
||||
# 启动服务
|
||||
pnpm run dev
|
||||
```
|
||||
浏览器访问 http://localhost:8015
|
||||
浏览器访问 http://localhost:8067
|
||||
|
||||
#### 登录相关
|
||||
登录api,对接后台接口有两种方式:
|
||||
@@ -713,8 +369,16 @@ pnpm run dev
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(new RegExp(`^/api/m1/lcode`), '/'),
|
||||
},
|
||||
|
||||
['/api/m1/xm']: {
|
||||
target: 'http://localhost:7067',
|
||||
ws: false,
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(new RegExp(`^/api/m1/xm`), '/'),
|
||||
},
|
||||
```
|
||||
上述代理实现把以/api/m1/lcode开头的请求地址(举例/api/m1/lcode/user/list)替换为/user/list,并转发到http://localhost:7014地址
|
||||
上述代理实现把以/api/m1/lcode 开头的请求地址(举例/api/m1/lcode/user/list)替换为/user/list,并转发到http://localhost:7014地址
|
||||
上述代理实现把以/api/m1/xm 开头的请求地址(举例/api/m1/xm/user/list)替换为/user/list,并转发到http://localhost:7067地址
|
||||
|
||||
2. 只启动前端页面工程,后端工程不启动,后端工程使用服务器上的已启动的服务
|
||||
此种情况下前端如何把请求转发到服务上起的后端服务?主要修改[vite.config.js](vite.config.ts)中的代理实现
|
||||
@@ -725,8 +389,14 @@ pnpm run dev
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(new RegExp(`^/api/m1/lcode`), '/'),
|
||||
},
|
||||
|
||||
['/api/m1/xm']: {
|
||||
target: '服务器上的ip:7067',
|
||||
ws: false,
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(new RegExp(`^/api/m1/xm`), '/'),
|
||||
},
|
||||
```
|
||||
上述代理实现把以/api/m1/lcode开头的请求地址(举例/api/m1/lcode/user/list)替换为/user/list,并转发到http://服务器上的ip:7014地址
|
||||
|
||||
### 构建
|
||||
|
||||
@@ -740,11 +410,11 @@ pnpm run build:prod
|
||||
|
||||
### 发布
|
||||
假设:
|
||||
1. 应用服务器(sit1-backend),ip为192.168.0.222,端口7014
|
||||
1. 应用服务器(sit1-backend),ip为192.168.0.222,端口7067
|
||||
2. 静态资源服务器(sit1-static),ip为192.168.0.111
|
||||
3. 反向代理使用nginx
|
||||
4. 静态资源部署到服务器sit1-static的/data/nginx/html/lcode/下
|
||||
5. 本地*ui-web目录在C:/Users/xxx/IdeaProjects/mdp-lcode-ui-web/
|
||||
4. 静态资源部署到服务器sit1-static的/data/nginx/html/xm/下
|
||||
5. 本地*ui-web目录在C:/Users/xxx/IdeaProjects/xm-ui-web/
|
||||
|
||||
#### 发布静态资源到测试\生产环境
|
||||
|
||||
@@ -759,7 +429,7 @@ rm -rf dist.rar
|
||||
# 2.执行rz命令,弹框选择本地dist文件上传到sit1-static服务器
|
||||
rz
|
||||
|
||||
# 3.在弹出的目录选择器中进入C:\Users\xxx\IdeaProjects\mdp-lcode-ui-web\dist\目录下
|
||||
# 3.在弹出的目录选择器中进入C:\Users\xxx\IdeaProjects\xm-ui-web\dist\目录下
|
||||
全选所有文件->右键->添加到dist.rar->选中dist.rar->上传到服务器商/data/nginx/html/lcode/目录下
|
||||
|
||||
# 4.执行解压缩命令,至此静态资源发布完成
|
||||
@@ -839,7 +509,7 @@ unrar x dist.rar
|
||||
```
|
||||
|
||||
#### 发布后端服务
|
||||
具体以[mdp-lcode-backend](https://gitee.com/maimengcloud/mdp-lcode-backend)中发布描述为准
|
||||
具体以[xm-backend](https://gitee.com/maimengcloud/xm-backend)中发布描述为准
|
||||
|
||||
### 运维
|
||||
#### 日志查询
|
||||
@@ -881,10 +551,10 @@ consule 的默认控制台
|
||||
http://ip:8500/
|
||||
|
||||
#### 有时候微服务需要人为干预进行下架
|
||||
可以调用[/bin/service-deregister.sh](https://gitee.com/maimengcloud/mdp-lcode-backend/blob/master/bin/service-deregister.sh)进行
|
||||
可以调用[/bin/service-deregister.sh](https://gitee.com/maimengcloud/xm-backend/blob/master/bin/service-deregister.sh)进行
|
||||
|
||||
#### 日志定时备份清理
|
||||
可以在crontab中配置定时任务,定时调用[bin/clear-log.sh](https://gitee.com/maimengcloud/mdp-lcode-backend/blob/master/bin/clear-log.sh)即可完成7天循环自动清理及备份日志
|
||||
可以在crontab中配置定时任务,定时调用[bin/clear-log.sh](https://gitee.com/maimengcloud/xm-backend/blob/master/bin/clear-log.sh)即可完成7天循环自动清理及备份日志
|
||||
|
||||
使用举例:
|
||||
```bash
|
||||
@@ -971,7 +641,7 @@ pnpm config set registry https://registry.npmmirror.com/
|
||||
|
||||
#### 数据库脚本在哪?
|
||||
答复: 数据库脚本一般存放在后端工程下的sql/文件夹下
|
||||
低代码的[mdp-lcode-backend/mdp-lcode/sql/lcode.sql](https://gitee.com/maimengcloud/mdp-lcode-backend/tree/master/mdp-lcode/sql)
|
||||
低代码的[xm-backend/xm/sql/lcode.sql](https://gitee.com/maimengcloud/xm-backend/tree/master/xm/sql)
|
||||
|
||||
#### 数据库的编码是什么?
|
||||
mysql的话,建议character set: utf8mb4, collation: utf8mb4_croatian_ci
|
||||
@@ -1102,13 +772,13 @@ VITE_MODULE_SCOPE=['模块编号1','模块编号2']
|
||||
## 💯 实践案例
|
||||
|
||||
1. [低代码平台](https://maimengcloud.com/lcode)
|
||||
1. [系统管理](https://maimengcloud.com/sys)
|
||||
1. [系统管理](https://maimengcloud.com/lcode)
|
||||
2. [协同办公](https://maimengcloud.com/oa)
|
||||
3. [唛盟众包-网页](https://maimengcloud.com)
|
||||
3. [项目管理-网页](https://maimengcloud.com/xm)
|
||||
4. 项目管理-小程序
|
||||
<img src="https://maimengcloud.com/img/77639c6907935d3b699f.png" alt="drawing" width="200"/>
|
||||
5. [流程管理](https://maimengcloud.com/workflow/)
|
||||
5. [流程管理](https://maimengcloud.com/lcode/)
|
||||
|
||||
### 项目分支说明
|
||||
|
||||
|
||||
BIN
docs/images/xm-jg/xm-1-jjzd.png
Normal file
|
After Width: | Height: | Size: 371 KiB |
BIN
docs/images/xm-jg/xm-10-xmjh.png
Normal file
|
After Width: | Height: | Size: 214 KiB |
BIN
docs/images/xm-jg/xm-11-zlgl.png
Normal file
|
After Width: | Height: | Size: 204 KiB |
BIN
docs/images/xm-jg/xm-12-ddgl.png
Normal file
|
After Width: | Height: | Size: 284 KiB |
BIN
docs/images/xm-jg/xm-13-xnfx.png
Normal file
|
After Width: | Height: | Size: 231 KiB |
BIN
docs/images/xm-jg/xm-2-xtgk.png
Normal file
|
After Width: | Height: | Size: 314 KiB |
BIN
docs/images/xm-jg/xm-3-xttd.png
Normal file
|
After Width: | Height: | Size: 316 KiB |
BIN
docs/images/xm-jg/xm-4-xtgn.png
Normal file
|
After Width: | Height: | Size: 368 KiB |
BIN
docs/images/xm-jg/xm-5-jsjg.png
Normal file
|
After Width: | Height: | Size: 480 KiB |
BIN
docs/images/xm-jg/xm-6-yyjg.png
Normal file
|
After Width: | Height: | Size: 364 KiB |
BIN
docs/images/xm-jg/xm-7-xtzs.png
Normal file
|
After Width: | Height: | Size: 313 KiB |
BIN
docs/images/xm-jg/xm-8-ztgl.png
Normal file
|
After Width: | Height: | Size: 385 KiB |
BIN
docs/images/xm-jg/xm-9-xqgl.png
Normal file
|
After Width: | Height: | Size: 196 KiB |
BIN
docs/images/xm-price/module-price.png
Normal file
|
After Width: | Height: | Size: 791 KiB |
BIN
docs/images/xm-price/service-price.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
docs/images/xm-zs/xm-zs-1-xmlx.png
Normal file
|
After Width: | Height: | Size: 240 KiB |
BIN
docs/images/xm-zs/xm-zs-10-ddwh.png
Normal file
|
After Width: | Height: | Size: 312 KiB |
BIN
docs/images/xm-zs/xm-zs-11-csgl.png
Normal file
|
After Width: | Height: | Size: 309 KiB |
BIN
docs/images/xm-zs/xm-zs-12-csbg.png
Normal file
|
After Width: | Height: | Size: 321 KiB |
BIN
docs/images/xm-zs/xm-zs-13-qxgl.png
Normal file
|
After Width: | Height: | Size: 329 KiB |
BIN
docs/images/xm-zs/xm-zs-14-cwfy.png
Normal file
|
After Width: | Height: | Size: 276 KiB |
BIN
docs/images/xm-zs/xm-zs-15-jsc.png
Normal file
|
After Width: | Height: | Size: 629 KiB |
BIN
docs/images/xm-zs/xm-zs-16-xnfx.png
Normal file
|
After Width: | Height: | Size: 288 KiB |
BIN
docs/images/xm-zs/xm-zs-17-rjt.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
docs/images/xm-zs/xm-zs-18-gzxfb.png
Normal file
|
After Width: | Height: | Size: 174 KiB |
BIN
docs/images/xm-zs/xm-zs-19-rwnlfb.png
Normal file
|
After Width: | Height: | Size: 119 KiB |
BIN
docs/images/xm-zs/xm-zs-2-xmzt.png
Normal file
|
After Width: | Height: | Size: 282 KiB |
BIN
docs/images/xm-zs/xm-zs-20-rwphb.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
docs/images/xm-zs/xm-zs-21-csylghfx.png
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
docs/images/xm-zs/xm-zs-22-xcx.png
Normal file
|
After Width: | Height: | Size: 332 KiB |
BIN
docs/images/xm-zs/xm-zs-23-spgl.png
Normal file
|
After Width: | Height: | Size: 374 KiB |
BIN
docs/images/xm-zs/xm-zs-24-csgl.png
Normal file
|
After Width: | Height: | Size: 350 KiB |
BIN
docs/images/xm-zs/xm-zs-3-zzjg.png
Normal file
|
After Width: | Height: | Size: 276 KiB |
BIN
docs/images/xm-zs/xm-zs-4-xmbg.png
Normal file
|
After Width: | Height: | Size: 310 KiB |
BIN
docs/images/xm-zs/xm-zs-5-xqgl.png
Normal file
|
After Width: | Height: | Size: 492 KiB |
BIN
docs/images/xm-zs/xm-zs-6-yhgs.png
Normal file
|
After Width: | Height: | Size: 183 KiB |
BIN
docs/images/xm-zs/xm-zs-7-xmjh.png
Normal file
|
After Width: | Height: | Size: 476 KiB |
BIN
docs/images/xm-zs/xm-zs-8-jhrw.png
Normal file
|
After Width: | Height: | Size: 180 KiB |
BIN
docs/images/xm-zs/xm-zs-9-ddgl.png
Normal file
|
After Width: | Height: | Size: 236 KiB |
@@ -105,6 +105,8 @@ export const editCategory = params => { return axios.post(`/${arcBase}/mdp/arc/
|
||||
//新增一条档案类目
|
||||
export const addCategory = params => { return axios.post(`/${arcBase}/mdp/arc/pub/category/add`, params); }
|
||||
|
||||
export const batchChangeParent= params => { return axios.post(`/${arcBase}/mdp/arc/pub/category/batchChangeParent`, params); }
|
||||
|
||||
//查询分类权限
|
||||
export const listCategoryQx = params => { return axios.get(`/${arcBase}/mdp/arc/pub/categoryQx/list`, { params: params }); }
|
||||
|
||||
|
||||
@@ -65,6 +65,8 @@ addDept: params => { return axios.post(`/${sysBase}/mdp/sys/dept/add`, params )
|
||||
editDept: params => { return axios.post(`/${sysBase}/mdp/sys/dept/edit`, params ); },
|
||||
delDept: params => { return axios.post(`/${sysBase}/mdp/sys/dept/del`, params ); },
|
||||
|
||||
batchChangeDeptParent: params => { return axios.post(`/${sysBase}/mdp/sys/dept/batchChangeParent`, params ); },
|
||||
|
||||
|
||||
/**
|
||||
* 角色列表
|
||||
|
||||
@@ -27,6 +27,10 @@ export const editXmFunc = params => { return axios.post(`${base}/xm/core/xmFunc/
|
||||
//新增一条功能模块表
|
||||
export const addXmFunc = params => { return axios.post(`${base}/xm/core/xmFunc/add`, params); };
|
||||
|
||||
|
||||
//批量更新上级
|
||||
export const batchChangeParent = params => { return axios.post(`${base}/xm/core/xmFunc/batchChangeParent`, params); };
|
||||
|
||||
//批量修改某些字段
|
||||
export const editSomeFieldsXmFunc = params => { return axios.post(`${base}/xm/core/xmFunc/editSomeFields`, params); };
|
||||
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
import axios from '@/config/maxios'
|
||||
|
||||
|
||||
import config from '@/api/mdp_pub/mdp_config'
|
||||
|
||||
let base = config.getXmCtx();
|
||||
|
||||
/**-------------------------与后端通讯接口------------------请写在下面-------------------------------------------- */
|
||||
/**
|
||||
* 项目人力成本预算
|
||||
*1 默认只开放普通查询,所有查询,只要上传 分页参数 {pageNum:当前页码从1开始,pageSize:每页记录数,total:总记录【数如果是0后台会自动计算总记录数非0不会自动计算】},后台都会自动按分页查询 其它 api用到再打开,没用到的api请注释掉,
|
||||
*2 查询、新增、修改的参数格式 params={id:'主键 主键',projectId:'项目编号',budgetAt:'预算金额',remark:'备注',subjectId:'预算科目',bizSdate:'费用归属周期开始日期',bizEdate:'费用归属周期结束日期',instId:'当前流程实例编号',bizFlowState:'当前流程状态0初始1审批中2审批通过3审批不通过4流程取消或者删除',costType:'成本类型0非人力1内部人力2外购人力',bizMonth:'费用归属月份yyyy-MM',subjectName:'科目名称',branchId:'项目归属企业编号'}
|
||||
**/
|
||||
|
||||
//普通查询 条件之间and关系
|
||||
export const listXmBudgetNlabor = params => { return axios.get(`${base}/xm/core/xmBudgetNlabor/list`, { params: params }); };
|
||||
|
||||
//删除一条项目人力成本预算 params={id:'主键 主键'}
|
||||
export const delXmBudgetNlabor = params => { return axios.post(`${base}/xm/core/xmBudgetNlabor/del`,params); };
|
||||
|
||||
//批量删除项目人力成本预算 params=[{id:'主键 主键'}]
|
||||
export const batchDelXmBudgetNlabor = params => { return axios.post(`${base}/xm/core/xmBudgetNlabor/batchDel`, params); };
|
||||
|
||||
//批量新增项目人力成本预算 params=[{id:'主键 主键'}]
|
||||
export const batchAddXmBudgetNlabor = params => { return axios.post(`${base}/xm/core/xmBudgetNlabor/batchAdd`, params); };
|
||||
|
||||
//修改一条项目人力成本预算记录
|
||||
export const editXmBudgetNlabor = params => { return axios.post(`${base}/xm/core/xmBudgetNlabor/edit`, params); };
|
||||
|
||||
//新增一条项目人力成本预算
|
||||
export const addXmBudgetNlabor = params => { return axios.post(`${base}/xm/core/xmBudgetNlabor/add`, params); };
|
||||
|
||||
//批量修改某些字段
|
||||
export const editSomeFieldsXmBudgetNlabor = params => { return axios.post(`${base}/xm/core/xmBudgetNlabor/editSomeFields`, params); };
|
||||
|
||||
|
||||
export const listSumXmBudgetNlabor = params => { return axios.get(`${base}/xm/core/xmBudgetNlabor/listSum`, { params: params }); };
|
||||
@@ -13,25 +13,26 @@ let base = config.getXmCtx();
|
||||
**/
|
||||
|
||||
//普通查询 条件之间and关系
|
||||
export const listXmBudgetLabor = params => { return axios.get(`${base}/xm/core/xmBudgetLabor/list`, { params: params }); };
|
||||
export const listXmBudgetRecord = params => { return axios.get(`${base}/xm/core/xmBudgetRecord/list`, { params: params }); };
|
||||
|
||||
//删除一条项目人力成本预算 params={id:'主键 主键'}
|
||||
export const delXmBudgetLabor = params => { return axios.post(`${base}/xm/core/xmBudgetLabor/del`,params); };
|
||||
export const delXmBudgetRecord = params => { return axios.post(`${base}/xm/core/xmBudgetRecord/del`,params); };
|
||||
|
||||
//批量删除项目人力成本预算 params=[{id:'主键 主键'}]
|
||||
export const batchDelXmBudgetLabor = params => { return axios.post(`${base}/xm/core/xmBudgetLabor/batchDel`, params); };
|
||||
export const batchDelXmBudgetRecord = params => { return axios.post(`${base}/xm/core/xmBudgetRecord/batchDel`, params); };
|
||||
|
||||
//批量新增项目人力成本预算 params=[{id:'主键 主键'}]
|
||||
export const batchAddXmBudgetLabor = params => { return axios.post(`${base}/xm/core/xmBudgetLabor/batchAdd`, params); };
|
||||
export const batchAddXmBudgetRecord = params => { return axios.post(`${base}/xm/core/xmBudgetRecord/batchAdd`, params); };
|
||||
|
||||
//修改一条项目人力成本预算记录
|
||||
export const editXmBudgetLabor = params => { return axios.post(`${base}/xm/core/xmBudgetLabor/edit`, params); };
|
||||
export const editXmBudgetRecord = params => { return axios.post(`${base}/xm/core/xmBudgetRecord/edit`, params); };
|
||||
|
||||
//新增一条项目人力成本预算
|
||||
export const addXmBudgetLabor = params => { return axios.post(`${base}/xm/core/xmBudgetLabor/add`, params); };
|
||||
export const addXmBudgetRecord = params => { return axios.post(`${base}/xm/core/xmBudgetRecord/add`, params); };
|
||||
|
||||
//批量修改某些字段
|
||||
export const editSomeFieldsXmBudgetLabor = params => { return axios.post(`${base}/xm/core/xmBudgetLabor/editSomeFields`, params); };
|
||||
export const editSomeFieldsXmBudgetRecord = params => { return axios.post(`${base}/xm/core/xmBudgetRecord/editSomeFields`, params); };
|
||||
|
||||
export const listSumXmBudgetLabor = params => { return axios.get(`${base}/xm/core/xmBudgetLabor/listSum`, { params: params }); };
|
||||
|
||||
export const listSumXmBudgetRecord = params => { return axios.get(`${base}/xm/core/xmBudgetRecord/listSum`, { params: params }); };
|
||||
//拆分一条项目人力成本预算
|
||||
export const splitXmBudgetRecord = params => { return axios.post(`${base}/xm/core/xmBudgetRecord/split`, params); };
|
||||
@@ -13,23 +13,23 @@ let base = config.getXmCtx();
|
||||
**/
|
||||
|
||||
//普通查询 条件之间and关系
|
||||
export const listXmCostNlabor = params => { return axios.get(`${base}/xm/core/xmCostNlabor/list`, { params: params }); };
|
||||
export const listXmCostRecord = params => { return axios.get(`${base}/xm/core/xmCostRecord/list`, { params: params }); };
|
||||
|
||||
//删除一条项目实际人工成本费用 params={id:'主键 主键'}
|
||||
export const delXmCostNlabor = params => { return axios.post(`${base}/xm/core/xmCostNlabor/del`,params); };
|
||||
export const delXmCostRecord = params => { return axios.post(`${base}/xm/core/xmCostRecord/del`,params); };
|
||||
|
||||
//批量删除项目实际人工成本费用 params=[{id:'主键 主键'}]
|
||||
export const batchDelXmCostNlabor = params => { return axios.post(`${base}/xm/core/xmCostNlabor/batchDel`, params); };
|
||||
export const batchDelXmCostRecord = params => { return axios.post(`${base}/xm/core/xmCostRecord/batchDel`, params); };
|
||||
|
||||
//修改一条项目实际人工成本费用记录
|
||||
export const editXmCostNlabor = params => { return axios.post(`${base}/xm/core/xmCostNlabor/edit`, params); };
|
||||
export const editXmCostRecord = params => { return axios.post(`${base}/xm/core/xmCostRecord/edit`, params); };
|
||||
|
||||
//新增一条项目实际人工成本费用
|
||||
export const addXmCostNlabor = params => { return axios.post(`${base}/xm/core/xmCostNlabor/add`, params); };
|
||||
export const addXmCostRecord = params => { return axios.post(`${base}/xm/core/xmCostRecord/add`, params); };
|
||||
|
||||
//批量修改某些字段
|
||||
export const editSomeFieldsXmCostNlabor = params => { return axios.post(`${base}/xm/core/xmCostNlabor/editSomeFields`, params); };
|
||||
export const editSomeFieldsXmCostRecord = params => { return axios.post(`${base}/xm/core/xmCostRecord/editSomeFields`, params); };
|
||||
|
||||
|
||||
//普通查询 条件之间and关系
|
||||
export const listSumXmCostNlabor = params => { return axios.get(`${base}/xm/core/xmCostNlabor/listSum`, { params: params }); };
|
||||
export const listSumXmCostRecord = params => { return axios.get(`${base}/xm/core/xmCostRecord/listSum`, { params: params }); };
|
||||
@@ -15,7 +15,8 @@ import MdpFormData from './mdp-expand/FormData.vue'
|
||||
import MdpFormExpand from './mdp-expand/FormExpand.vue'
|
||||
import MdpColumnExpand from './mdp-expand/ColumnExpand.vue'
|
||||
import MdpFuncMenu from './mdp-func-menu/Index.vue'
|
||||
import MdpFocus from './mdp-focus/Index.vue'
|
||||
import MdpFocus from './mdp-focus/Index.vue'
|
||||
import MdpSelectBranch from './mdp-select-branch/Index.vue'
|
||||
|
||||
const compLists = {
|
||||
install: function(Vue) {
|
||||
@@ -38,6 +39,7 @@ const compLists = {
|
||||
Vue.component('MdpColumnExpand', MdpColumnExpand)
|
||||
Vue.component('MdpFuncMenu',MdpFuncMenu)
|
||||
Vue.component('MdpFocus',MdpFocus)
|
||||
Vue.component('MdpSelectBranch',MdpSelectBranch)
|
||||
}
|
||||
}
|
||||
export default compLists
|
||||
@@ -1,235 +1,178 @@
|
||||
<template>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<el-space wrap>
|
||||
|
||||
<mdp-select style="width:100%" :disabled="categoryType" v-model="filters.categoryType" item-code="categoryType" placeholder="请选择主题" clearable @change="onCategoryTypeChange"/>
|
||||
<el-button icon="plus" type="primary" plain @click.prevent.stop="addTopNode()" title="添加顶级分类,在分类上右键可以添加子分类"/>
|
||||
<el-button v-if="showConfirm" type="warning" @click="confirm" title="确认选择" icon="check"/>
|
||||
<el-input v-model="filters.key" placeholder="名称"/>
|
||||
</el-space>
|
||||
</template>
|
||||
<el-tree accordion v-if="show"
|
||||
:props="defaultTreeProps"
|
||||
:filter-node-method="filterNode"
|
||||
:show-checkbox="showCheckbox"
|
||||
:default-expand-all="defaultExpandAll"
|
||||
:expand-on-click-node="expandOnClickNode"
|
||||
:node-key="nodeKey_"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
:default-checked-keys="defaultCheckedKeys"
|
||||
auto-expand-parent
|
||||
@check-change="handleCheckChange"
|
||||
@current-change="handleCurrentChange"
|
||||
@node-click="handleNodeClick"
|
||||
:check-strictly="true"
|
||||
:check-on-click-node="true"
|
||||
lazy
|
||||
:load="loadNode"
|
||||
ref="nodeTree" @contextmenu.prevent>
|
||||
<template #default="{ node, data}">
|
||||
<div class="custom-tree-node" @contextmenu.prevent title="右键可以增删改">
|
||||
<el-popover
|
||||
:open-delay="1000"
|
||||
placement="top-start"
|
||||
:width="showConfirm?300:200"
|
||||
trigger="contextmenu" >
|
||||
|
||||
<el-button icon="plus" circle type="success" v-if=" !(!data.id || data.id=='C0'||data.id=='0')" @click.prevent.stop="addNode(data,node)" title="添加子分类"/>
|
||||
<el-button icon="edit" circle type="warning" v-if=" !(!data.id || data.id=='C0'||data.id=='0')" @click.prevent.stop="editNode(data,node)" title="修改名字"/>
|
||||
<el-button icon="delete" circle type="danger" v-if=" !(!data.id || data.id=='C0'||data.id=='0')" @click.prevent.stop="deleteNode(data,node)" title="删除该分类"/>
|
||||
<template>
|
||||
<MdpTree
|
||||
ref="nodeTree"
|
||||
title="功能模块"
|
||||
showCheckbox
|
||||
:props="propsCpd"
|
||||
:load="listCategory"
|
||||
:del="delCategory"
|
||||
:batchDel="batchDelCategory"
|
||||
:multiple="multiple"
|
||||
:showConfirm="showConfirm"
|
||||
:hidden="hiddenCpd"
|
||||
@addTopNode="(cb) => onAddTopClick(cb)"
|
||||
@editNode="(d, cb, subcb) => onEditClick(d, cb, subcb)"
|
||||
@addSubNode="(p, cb) => onAddSubClick(p, cb)"
|
||||
@changePid="(cks,cb) => onChangePidClick(cks,cb)"
|
||||
@confirm = "(d)=>{$emit('confirm',d);$emit('select',d)}"
|
||||
@check-change="(d,c,i)=>$emit('check-change',d,c,i)"
|
||||
@node-click="(d,n,c)=>$emit('node-click',d,n,c)"
|
||||
rootId="C0"
|
||||
:draggable="true"
|
||||
>
|
||||
<template #topToolbar>
|
||||
<mdp-select width="250px" :disabled="categoryType" v-model="filters.categoryType" item-code="categoryType" placeholder="主题" clearable @change="onCategoryTypeChange"/>
|
||||
</template>
|
||||
<template #nodeName="{ data }">
|
||||
<el-space>
|
||||
<div><Icon v-if="data.imageUrls" :icon="data.imageUrls"/>{{data.name}}</div>
|
||||
</el-space>
|
||||
</template>
|
||||
<template #nodeToolbar="{data}">
|
||||
<el-button type="primary" v-if="data.qxLvl=='2'" @click="$refs['qxSetDialog'].open({category:data})">配置限制规则</el-button>
|
||||
</template>
|
||||
</MdpTree>
|
||||
|
||||
<template #reference><div style="display:flex;align-items:center;width:100%;"><Icon v-if="data.imageUrls" :icon="data.imageUrls"/>{{data.name}}</div></template>
|
||||
</el-popover>
|
||||
</div>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-card>
|
||||
<el-dialog
|
||||
title="新增分类"
|
||||
v-model="addVisible"
|
||||
width="60%" append-to-body>
|
||||
<el-form ref="addCategory" :model="addCategory" label-width="200" >
|
||||
<!--编辑 Category xm_project_func界面-->
|
||||
<mdp-dialog ref="editDialog" width="30%" append-to-body :close-on-click-modal="false">
|
||||
<template #default="{ data,dialog }">
|
||||
<el-form ref="editForm" :model="editForm" label-width="150" >
|
||||
<el-form-item label="主题" prop="categoryType" :rules="[
|
||||
{ required: true, message: '主题不能为空'}
|
||||
]">
|
||||
<mdp-select v-model="addCategory.categoryType" :disabled="currentCategory?.categoryType" item-code="categoryType" placeholder="请选择主题"/>
|
||||
<mdp-select width="100%" v-model="editForm.categoryType" item-code="categoryType" placeholder="请选择主题" :disabled="data.formData.categoryType"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="分类编号" prop="id" :rules="[
|
||||
{ required: true, message: '不能为空'}
|
||||
]">
|
||||
{{editForm.id}}
|
||||
</el-form-item>
|
||||
<el-form-item label="分类名称" prop="name"
|
||||
:rules="[
|
||||
{ required: true, message: '名称不能为空'}
|
||||
]">
|
||||
<el-input v-model="editForm.name" />
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="图标" >
|
||||
<IconSelect v-model="editForm.imageUrls"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="配置" >
|
||||
<el-checkbox v-model="editForm.isLeaf" auto-complete="off" true-label="0" false-label="1">是否可添加子分类</el-checkbox>
|
||||
|
||||
<el-checkbox v-model="editForm.limitType" auto-complete="off" true-label="1" false-label="2">文章数目是否限制为1篇</el-checkbox>
|
||||
|
||||
<el-checkbox v-model="editForm.isAuth" auto-complete="off" true-label="1" false-label="0">文章发布是否需要审核</el-checkbox>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="权限" >
|
||||
<el-radio v-model="editForm.qxLvl" auto-complete="off" label="0">全网公开</el-radio>
|
||||
<el-radio v-model="editForm.qxLvl" auto-complete="off" label="1">内部公开</el-radio>
|
||||
<el-radio v-model="editForm.qxLvl" auto-complete="off" label="2">受限</el-radio>
|
||||
<el-button type="primary" v-if="editForm.qxLvl=='2'" @click="$refs['qxSetDialog'].open({category:editCategory})">配置限制规则</el-button>
|
||||
<el-checkbox v-model="editForm.pqx" auto-complete="off" true-label="1" false-label="0">所有子类遵守上级权限规则</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div class="footer">
|
||||
<el-button @click="dialog.close()">关 闭</el-button>
|
||||
<el-button type="primary" v-loading="loading.edit" @click="editSubmit(data.callback)">确 定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
|
||||
<!--新增 Category xm_project_func界面-->
|
||||
<mdp-dialog ref="addDialog" width="30%" append-to-body :close-on-click-modal="false">
|
||||
<template #default="{ data, dialog }">
|
||||
<el-form ref="addForm" :model="addForm" label-width="150" >
|
||||
<el-form-item label="主题" prop="categoryType" :rules="[
|
||||
{ required: true, message: '主题不能为空'}
|
||||
]">
|
||||
<mdp-select width="100%" v-model="addForm.categoryType" :disabled="data.parent && data.parent.categoryType" item-code="categoryType" placeholder="请选择主题"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="上级分类">
|
||||
|
||||
<el-tag>{{ currentCategory && currentCategory.id && currentCategory.id!='C0'? "上级:"+currentCategory.name:"顶级分类C0" }}</el-tag>
|
||||
<el-tag>{{ data.parent && data.parent.id && data.parent.id!='C0'? "上级:"+data.parent.name:"顶级分类C0" }}</el-tag>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item label="分类编号">
|
||||
<el-input v-model="addCategory.id" placeholder="如果为空,则系统自动生成"/>
|
||||
<el-form-item label="分类编号" prop="id" :rules="[
|
||||
{ required: true, message: '不能为空'}
|
||||
]">
|
||||
<el-input v-model="addForm.id" placeholder="如果为空,则系统自动生成"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="分类名称" prop="name"
|
||||
:rules="[
|
||||
{ required: true, message: '名称不能为空'}
|
||||
]">
|
||||
<el-input v-model="addCategory.name" />
|
||||
<el-input v-model="addForm.name" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="图标" >
|
||||
<IconSelect v-model="addCategory.imageUrls"/>
|
||||
<IconSelect v-model="addForm.imageUrls"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="配置" prop="name">
|
||||
<el-checkbox v-model="addCategory.isLeaf" auto-complete="off" true-label="0" false-label="1">是否可添加子分类</el-checkbox>
|
||||
<el-checkbox v-model="addForm.isLeaf" auto-complete="off" true-label="0" false-label="1">是否可添加子分类</el-checkbox>
|
||||
|
||||
<el-checkbox v-model="addCategory.limitType" auto-complete="off" true-label="1" false-label="2">文章数目是否限制为1篇</el-checkbox>
|
||||
<el-checkbox v-model="addForm.limitType" auto-complete="off" true-label="1" false-label="2">文章数目是否限制为1篇</el-checkbox>
|
||||
|
||||
<el-checkbox v-model="addCategory.isAuth" auto-complete="off" true-label="1" false-label="0">文章发布是否需要审核</el-checkbox>
|
||||
<el-checkbox v-model="addForm.isAuth" auto-complete="off" true-label="1" false-label="0">文章发布是否需要审核</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item label="权限" >
|
||||
<el-radio v-model="addCategory.qxLvl" auto-complete="off" label="0">全网公开</el-radio>
|
||||
<el-radio v-model="addCategory.qxLvl" auto-complete="off" label="1">内部公开</el-radio>
|
||||
<el-radio v-model="addCategory.qxLvl" auto-complete="off" label="2">受限</el-radio>
|
||||
<el-checkbox v-model="addCategory.pqx" auto-complete="off" true-label="1" false-label="0">所有子类遵守上级权限规则</el-checkbox>
|
||||
<el-radio v-model="addForm.qxLvl" auto-complete="off" label="0">全网公开</el-radio>
|
||||
<el-radio v-model="addForm.qxLvl" auto-complete="off" label="1">内部公开</el-radio>
|
||||
<el-radio v-model="addForm.qxLvl" auto-complete="off" label="2">受限</el-radio>
|
||||
<el-checkbox v-model="addForm.pqx" auto-complete="off" true-label="1" false-label="0">所有子类遵守上级权限规则</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="addVisible = false">关闭</el-button>
|
||||
<el-button type="primary" v-loading="addLoading" @click="addCategorySubmit">确 定</el-button>
|
||||
<div class="footer">
|
||||
<el-button @click="dialog.close()">关闭</el-button>
|
||||
<el-button type="primary" v-loading="loading.add" @click="addSubmit(data.parent,data.callback)">确 定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
title="修改分类提示"
|
||||
v-model="editVisible"
|
||||
width="60%" append-to-body>
|
||||
<el-form ref="editCategory" :model="editCategory" label-width="200" >
|
||||
<el-form-item label="主题" prop="categoryType" :rules="[
|
||||
{ required: true, message: '主题不能为空'}
|
||||
]">
|
||||
<mdp-select v-model="editCategory.categoryType" item-code="categoryType" placeholder="请选择主题" :disabled="editCategory.categoryType"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="分类编号" prop="id">
|
||||
{{editCategory.id}}
|
||||
</el-form-item>
|
||||
<el-form-item label="分类名称" prop="name"
|
||||
:rules="[
|
||||
{ required: true, message: '名称不能为空'}
|
||||
]">
|
||||
<el-input v-model="editCategory.name" />
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="图标" >
|
||||
<IconSelect v-model="editCategory.imageUrls"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="配置" >
|
||||
<el-checkbox v-model="editCategory.isLeaf" auto-complete="off" true-label="0" false-label="1">是否可添加子分类</el-checkbox>
|
||||
|
||||
<el-checkbox v-model="editCategory.limitType" auto-complete="off" true-label="1" false-label="2">文章数目是否限制为1篇</el-checkbox>
|
||||
|
||||
<el-checkbox v-model="editCategory.isAuth" auto-complete="off" true-label="1" false-label="0">文章发布是否需要审核</el-checkbox>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="权限" >
|
||||
<el-radio v-model="editCategory.qxLvl" auto-complete="off" label="0">全网公开</el-radio>
|
||||
<el-radio v-model="editCategory.qxLvl" auto-complete="off" label="1">内部公开</el-radio>
|
||||
<el-radio v-model="editCategory.qxLvl" auto-complete="off" label="2">受限</el-radio>
|
||||
<el-button type="primary" v-if="editCategory.qxLvl=='2'" @click="$refs['qxSetDialog'].open({category:editCategory})">配置限制规则</el-button>
|
||||
<el-checkbox v-model="editCategory.pqx" auto-complete="off" true-label="1" false-label="0">所有子类遵守上级权限规则</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="editVisible = false">关 闭</el-button>
|
||||
<el-button type="primary" v-loading="editLoading" @click="editCategorySubmit">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<mdp-dialog ref="qxSetDialog">
|
||||
</mdp-dialog>
|
||||
<mdp-dialog ref="qxSetDialog">
|
||||
<template #default="{visible,data,dialog}">
|
||||
<category-qx-set :visible="visible" :category="data.category" @close="dialog.close()" @submit="dialog.close()"/>
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util' //全局公共库
|
||||
|
||||
import CategoryQxSet from './QxSet.vue';
|
||||
import {
|
||||
addCategory,
|
||||
editCategory,
|
||||
delCategory,
|
||||
batchDelCategory,
|
||||
listCategory,
|
||||
batchChangeParent,
|
||||
} from '@/api/mdp_pub/larc'
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import CategoryQxSet from './QxSet.vue';
|
||||
export default {
|
||||
components:{
|
||||
CategoryQxSet
|
||||
},
|
||||
watch: {
|
||||
nodeFilterText(val) {
|
||||
this.$refs.nodeTree.filter(val);
|
||||
},
|
||||
checkedKeys(val){
|
||||
this.$refs.nodeTree.setCheckedKeys(val);
|
||||
},
|
||||
refresh(val){
|
||||
},
|
||||
currentKey(val){
|
||||
this.$refs.nodeTree.setCheckedKeys([val]);
|
||||
},
|
||||
value(val){
|
||||
this.nodeid=val;
|
||||
},
|
||||
nodeid(val){
|
||||
this.$emit('input',val);
|
||||
},
|
||||
categoryType(val){
|
||||
//this.$refs.nodeTree.filter(this.filters.categoryType)
|
||||
},
|
||||
'filters.categoryType'(){
|
||||
this.getTreeData();
|
||||
},
|
||||
'filters.key'(v){
|
||||
this.$refs.nodeTree.filter(v)
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
|
||||
categoryTreeData() {
|
||||
return []
|
||||
},
|
||||
defaultExpandedKeys(){
|
||||
return this.defaultCheckedKeys;
|
||||
},
|
||||
defaultCheckedKeys(){
|
||||
if(this.value){
|
||||
return [this.value];
|
||||
}
|
||||
return this.checkedKeys;
|
||||
},
|
||||
nodeKey_(){
|
||||
return this.nodeKey?this.nodeKey:'id'
|
||||
},
|
||||
...mapState(useUserStore,[
|
||||
'userInfo'
|
||||
]),
|
||||
},
|
||||
props:{
|
||||
'value':String,Array,
|
||||
'branchId':String,
|
||||
'visible':{type:Boolean,default:false},
|
||||
'showCount':{type:Boolean,default:false},
|
||||
'showRoot':{type:Boolean,default:false},
|
||||
'countTips':String,
|
||||
'showFilter':{type:Boolean,default:false},
|
||||
'multiple':{type:Boolean,default:false},
|
||||
'checkedKeys':Array,
|
||||
'refresh':{type:Boolean,default:false},
|
||||
'defaultExpandAll':{type:Boolean,default:false},
|
||||
'expandOnClickNode':{type:Boolean,default:false},
|
||||
showCheckbox:{type:Boolean,default:false},
|
||||
showConfirm:{type:Boolean,default:false},
|
||||
'indent':Number,
|
||||
categoryType:{type:String,default:null},
|
||||
nodeKey:String,
|
||||
|
||||
export default {
|
||||
props: {
|
||||
'subOpType':{type:String,defalut:'mng'},
|
||||
'multiple':{type:Boolean,default:false},
|
||||
'showConfirm':{type:Boolean,default:false},
|
||||
'hidden':{type:Object,default:()=>null},
|
||||
'params':{type:Object,default:()=>null},
|
||||
'clearable':{type:Boolean,default:true},
|
||||
categoryType:{//主题
|
||||
type:String,
|
||||
default:null
|
||||
},
|
||||
/**
|
||||
* 上级分类
|
||||
*/
|
||||
pid:{
|
||||
pid:{
|
||||
type:String,
|
||||
default:''
|
||||
},
|
||||
@@ -250,362 +193,181 @@ import CategoryQxSet from './QxSet.vue';
|
||||
default:''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filters:{
|
||||
categoryType:'',
|
||||
computed: {
|
||||
...mapState(useUserStore, ['userInfo', 'roles']),
|
||||
|
||||
hiddenCpd(){
|
||||
var isSelect=this.subOpType=='select'
|
||||
var hidden ={
|
||||
batchDel: isSelect,
|
||||
del:isSelect,
|
||||
changePid: false,
|
||||
addTop: isSelect,
|
||||
addSub: isSelect,
|
||||
edit: isSelect,
|
||||
filter: false,
|
||||
page: true,
|
||||
}
|
||||
hidden=Object.assign(hidden,this.hidden)
|
||||
return hidden
|
||||
},
|
||||
nodeFilterText: '',
|
||||
treeData:[],
|
||||
defaultTreeProps:{
|
||||
|
||||
id:this.nodeKey==null?'id':this.nodeKey,
|
||||
label:'name',
|
||||
children: 'children',
|
||||
isLeaf: function(n){
|
||||
return n.childNum<=0
|
||||
}
|
||||
},
|
||||
listLoading: false,
|
||||
addLoading:false,
|
||||
editLoading:false,
|
||||
nodeid:'',
|
||||
currentCategory:{id:'',pid:'',name:'',categoryType:null},
|
||||
addCategory:{id:'',pid:'',name:'',isLeaf:'0',isAuth:'0',limitType:'2',categoryType:'',pqx:'',qxLvl:''},
|
||||
editCategory:{id:'',pid:'',name:'',isLeaf:'0',isAuth:'0',limitType:'2',categoryType:'',pqx:'',qxLvl:''},
|
||||
addVisible:false,
|
||||
editVisible:false,
|
||||
options:{categoryType:[]},
|
||||
root:{},
|
||||
isAddTop:false,
|
||||
resolve:null,
|
||||
|
||||
show:true,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onCategoryTypeChange(v){
|
||||
this.getTreeData()
|
||||
propsCpd(){
|
||||
return { id: 'id', pid: 'pid', label: 'name' , isLeaf:(data,n)=>{
|
||||
return data.childNum<=0
|
||||
}}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filters: {
|
||||
categoryType: ''
|
||||
},
|
||||
unselect(){
|
||||
this.$refs['nodeTree'].setCurrentKey(null)
|
||||
},
|
||||
handleCheckChange(data, checked, indeterminate) {
|
||||
let checkedKeys=this.$refs.nodeTree.getCheckedKeys();
|
||||
console.log(this.multiple);
|
||||
if( this.multiple===undefined || this.multiple===false||this.multiple==='false'){
|
||||
if(checked==true){
|
||||
if(checkedKeys.length>1){
|
||||
this.$refs.nodeTree.setCheckedKeys([data[this.nodeKey_]]);
|
||||
this.$emit('check-change',data,checked,indeterminate);
|
||||
this.nodeid=data[this.nodeKey_];
|
||||
}else{
|
||||
this.$emit('check-change',data,checked,indeterminate);
|
||||
this.nodeid=data[this.nodeKey_];
|
||||
}
|
||||
}else{
|
||||
if(checkedKeys.length==0){
|
||||
this.nodeid='';
|
||||
this.$emit('check-change',data,checked,indeterminate);
|
||||
addForm:{id:'',pid:'',name:'',isLeaf:'0',isAuth:'0',limitType:'2',categoryType:'',pqx:'',qxLvl:''},
|
||||
editForm:{id:'',pid:'',name:'',isLeaf:'0',isAuth:'0',limitType:'2',categoryType:'',pqx:'',qxLvl:''},
|
||||
loading:{add:false,edit:false,list:false}
|
||||
}
|
||||
}, //end data
|
||||
methods: {
|
||||
listCategory(params, node) {
|
||||
Object.assign(params,this.filters)
|
||||
if(this.params){
|
||||
Object.assign(params,this.params)
|
||||
}
|
||||
return listCategory(params)
|
||||
},
|
||||
delCategory,
|
||||
batchDelCategory,
|
||||
//显示编辑界面 Category xm_project_func
|
||||
onEditClick: function (formData, callback, addSubCallback) {
|
||||
this.editForm={...formData}
|
||||
this.$refs['editDialog'].open({
|
||||
formData: formData,
|
||||
callback: callback,
|
||||
addSubCallback: addSubCallback
|
||||
})
|
||||
},
|
||||
//显示新增界面 Category xm_project_func
|
||||
onAddTopClick: function (callback) {
|
||||
var formData = {}
|
||||
if (!this.initExtParams(formData)) {
|
||||
return
|
||||
}
|
||||
|
||||
this.$refs['addDialog'].open({
|
||||
formData: formData,
|
||||
parent: null,
|
||||
callback: callback
|
||||
})
|
||||
},
|
||||
initExtParams(formData, parent) {
|
||||
if(this.categoryType){
|
||||
formData.categoryType=this.categoryType
|
||||
}
|
||||
return true
|
||||
},
|
||||
onAddSubClick: function (parent, callback) {
|
||||
var formData = {}
|
||||
if (!this.initExtParams(formData, parent)) {
|
||||
return
|
||||
}
|
||||
Object.assign(formData,parent)
|
||||
formData.pid=parent.id
|
||||
formData.id=null
|
||||
this.addForm={...formData}
|
||||
this.$refs['addDialog'].open({
|
||||
formData: formData,
|
||||
parent: parent,
|
||||
callback: callback
|
||||
})
|
||||
},
|
||||
onChangePidClick: function(idLinks,callback){
|
||||
batchChangeParent(idLinks).then(res=>{
|
||||
let {tips}=res
|
||||
if(tips.isOk){
|
||||
if(callback){
|
||||
callback(true)
|
||||
}
|
||||
this.$message.success(tips.msg)
|
||||
}else{
|
||||
this.$message.error(tips.msg)
|
||||
}
|
||||
}else{
|
||||
this.$emit('check-change',data,checked,indeterminate);
|
||||
}
|
||||
},
|
||||
handleCurrentChange(data, node) {
|
||||
this.$emit('current-change',data, node);
|
||||
},
|
||||
handleNodeClick(data, node, comp) {
|
||||
this.$emit('node-click',data, node, comp);
|
||||
},
|
||||
handleAddCategoryClose(){
|
||||
this.addVisible=false;
|
||||
},
|
||||
addCategorySubmit(){
|
||||
var branchId=this.userInfo.branchId
|
||||
var pid=""
|
||||
if(this.isAddTop){
|
||||
pid="C0"
|
||||
}else{
|
||||
pid=this.currentCategory.id
|
||||
branchId=this.currentCategory.branchId
|
||||
}
|
||||
this.addCategory.pid=pid
|
||||
this.addCategory.isShow='1'
|
||||
this.addCategory.branchId=branchId
|
||||
})
|
||||
},
|
||||
onCategoryTypeChange(ctype){
|
||||
this.$refs.nodeTree.refresh()
|
||||
},
|
||||
addSubmit(parent,callback){
|
||||
var branchId=this.userInfo.branchId
|
||||
|
||||
this.addForm.branchId=branchId
|
||||
if(this.crelyType){
|
||||
this.addCategory.crelyType=this.crelyType
|
||||
this.addForm.crelyType=this.crelyType
|
||||
}
|
||||
|
||||
if(this.crelyId){
|
||||
this.addCategory.crelyId=this.crelyId
|
||||
this.addForm.crelyId=this.crelyId
|
||||
}
|
||||
|
||||
if(this.crelyStype){
|
||||
this.addCategory.crelyStype=this.crelyStype
|
||||
this.addForm.crelyStype=this.crelyStype
|
||||
}
|
||||
|
||||
if(this.crelySid){
|
||||
this.addCategory.crelySid=this.crelySid
|
||||
this.addForm.crelySid=this.crelySid
|
||||
}
|
||||
this.$refs.addCategory.validate((valid) => {
|
||||
if(this.filters.categoryType){
|
||||
this.addForm.categoryType=this.filters.categoryType
|
||||
}
|
||||
if(this.categoryType){
|
||||
|
||||
this.addForm.categoryType=this.categoryType
|
||||
}
|
||||
this.$refs.addForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$confirm('确认提交吗?', '提示', {}).then(() => {
|
||||
this.addLoading = true;
|
||||
this.$mdp.addCategory(this.addCategory).then(res=>{
|
||||
this.addLoading=false;
|
||||
if(res.tips.isOk){
|
||||
|
||||
|
||||
this.$message.success(res.tips.msg);
|
||||
if(!this.isAddTop){
|
||||
if(this.currentCategory.children){
|
||||
this.currentCategory.children.push(res.data)
|
||||
}else{
|
||||
this.currentCategory.children=[res.data]
|
||||
}
|
||||
}else{
|
||||
this.$refs['nodeTree'].append(res.data,this.root)
|
||||
}
|
||||
|
||||
this.addVisible=false;
|
||||
this.loading.add = true;
|
||||
addCategory(this.addForm).then(res=>{
|
||||
this.loading.add=false;
|
||||
if(res.tips.isOk){
|
||||
this.$message.success(res.tips.msg);
|
||||
this.$refs.addDialog.close()
|
||||
callback(res.data)
|
||||
}else{
|
||||
this.$message.error(res.tips.msg);
|
||||
}
|
||||
}).catch(e=>this.addLoading = false );
|
||||
}).catch(e=>this.loading.add = false );
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
editCategorySubmit(){
|
||||
this.$refs.editCategory.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$confirm('确认提交吗?', '提示', {}).then(() => {
|
||||
this.editLoading = true;
|
||||
this.$mdp.editCategory(this.editCategory).then(res=>{
|
||||
//console.log("res--"+JSON.stringify(res));
|
||||
this.editLoading = false;
|
||||
if(res.tips.isOk){
|
||||
this.editVisible=false;
|
||||
this.$message.success(res.tips.msg);
|
||||
|
||||
this.$refs['nodeTree'].updateKeyChildren(res.data.id,res.data)
|
||||
this.editVisible=false
|
||||
}else{
|
||||
this.$message.error(res.tips.msg);
|
||||
}
|
||||
}).catch(e=>this.editLoading = false );
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
addTopNode(){
|
||||
this.isAddTop=true
|
||||
this.addVisible=true;
|
||||
this.addCategory.categoryType=this.categoryType||null
|
||||
return false;
|
||||
},
|
||||
addNode(data, node, comp) {
|
||||
this.isAddTop=false
|
||||
this.currentCategory=data
|
||||
this.addVisible=true;
|
||||
this.addCategory.categoryType=this.currentCategory?.categoryType||null
|
||||
return false;
|
||||
},
|
||||
editNode(data, node, comp) {
|
||||
this.editCategory=data
|
||||
this.editVisible=true;
|
||||
console.log("editNode__"+JSON.stringify(data));
|
||||
return false;
|
||||
},
|
||||
deleteNode(data, node, comp) {
|
||||
console.log("deleteNode__"+JSON.stringify(data));
|
||||
if(data.children){
|
||||
this.$message.error("请先删除子元素");
|
||||
return;
|
||||
}
|
||||
let params={
|
||||
id:data.id,
|
||||
branchId:data.branchId
|
||||
}
|
||||
if(!params.branchId){
|
||||
params.branchId=this.userInfo.branchId
|
||||
}
|
||||
this.$confirm('确认删除吗?', '提示', {}).then(() => {
|
||||
this.$mdp.delCategory(params).then(res=>{
|
||||
//console.log("res--"+JSON.stringify(res));
|
||||
if(res.tips.isOk){
|
||||
this.editVisible=false;
|
||||
|
||||
this.$refs['nodeTree'].remove(data)
|
||||
this.$message.success(res.tips.msg);
|
||||
}else{
|
||||
this.$message.error(res.tips.msg);
|
||||
}
|
||||
});
|
||||
})
|
||||
return false;
|
||||
},
|
||||
//获取分类树列表
|
||||
getTreeData(refresh) {
|
||||
this.show=false
|
||||
this.$nextTick(()=>{
|
||||
this.show=true
|
||||
})
|
||||
},
|
||||
|
||||
refreshNode(guid) {
|
||||
let node = this.$refs.nodeTree.getNode(guid)
|
||||
if (node && node.loaded) {
|
||||
node.loaded = false
|
||||
node.expand() // 主动调用展开节点方法,重新查询该节点下的所有子节点
|
||||
}
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
return data.name.includes(value);
|
||||
},
|
||||
renderContent(h, { node, data, store }) {
|
||||
var countMsg='';
|
||||
if(this.countTips){
|
||||
countMsg=this.countTips;
|
||||
}
|
||||
if(this.showCount==true || this.showCount=='true'){
|
||||
return h('div'[h('span',node.label+"("+data.count+countMsg+")")]) ;
|
||||
}else{
|
||||
return h('div',[h('span',node.label+"("+data.count+countMsg+")")]) ;
|
||||
//return h('span',"@contextmenu.prevent='contextmenu('"+node.id+"')',"+node.label+"("+(data.children==null?0:data.children.length)+countMsg+")") ;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
confirm(){
|
||||
var nodes= this.$refs.nodeTree.getCheckedNodes(false,false)
|
||||
if(this.multiple){
|
||||
this.$emit('confirm',nodes)
|
||||
}else{
|
||||
this.$emit('confirm',nodes&&nodes.length>0?nodes[0]:null)
|
||||
}
|
||||
|
||||
},
|
||||
setNodeData(data){
|
||||
if(!data){
|
||||
return;
|
||||
}
|
||||
if(data.imageUrls){
|
||||
return;
|
||||
}
|
||||
data.imageUrls=data.childNum>0?'fa-solid:folder':'fa:file-o'
|
||||
},
|
||||
loadNode(node, resolve) {
|
||||
if (node.level === 0) {
|
||||
|
||||
this.root=node
|
||||
this.resolve=resolve
|
||||
let params = {
|
||||
'pid':'C0'
|
||||
};
|
||||
if(this.categoryType){
|
||||
params.categoryType=this.categoryType
|
||||
}
|
||||
if(this.filters.categoryType){
|
||||
params.categoryType=this.filters.categoryType
|
||||
}
|
||||
this.listLoading = true;
|
||||
this.$mdp.listCategory(params).then((res) => {
|
||||
var tips=res.tips;
|
||||
var data=res.data;
|
||||
this.listLoading = false;
|
||||
this.expandRowKeys=data.map(i=>i.deptid)
|
||||
data.forEach(k=>this.setNodeData(k))
|
||||
resolve(data )
|
||||
|
||||
}).catch(() => {
|
||||
this.listLoading = false;
|
||||
});
|
||||
}else {
|
||||
setTimeout(() => {
|
||||
let params = {
|
||||
pid:node.data.id
|
||||
};
|
||||
this.listLoading = true;
|
||||
this.$mdp.listCategory(params).then((res) => {
|
||||
var tips=res.tips;
|
||||
var data=res.data;
|
||||
this.listLoading = false;
|
||||
|
||||
data.forEach(k=>this.setNodeData(k))
|
||||
resolve(data)
|
||||
|
||||
}).catch(() => {
|
||||
this.listLoading = false;
|
||||
});
|
||||
}, 500);
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.nodeid=this.value;
|
||||
}
|
||||
}
|
||||
editSubmit(callback){
|
||||
this.$refs.editForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$confirm('确认提交吗?', '提示', {}).then(() => {
|
||||
this.loading.edit = true;
|
||||
editCategory(this.editForm).then(res=>{
|
||||
if(res.tips.isOk){
|
||||
this.loading.edit = false
|
||||
this.$refs.editDialog.close();
|
||||
this.$message.success(res.tips.msg);
|
||||
callback(this.editForm)
|
||||
}else{
|
||||
this.$message.error(res.tips.msg);
|
||||
}
|
||||
}).catch(e=>this.loading.edit = false );
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}, //end methods
|
||||
components: { CategoryQxSet
|
||||
},
|
||||
mounted() {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
|
||||
|
||||
.custom-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
color: #4386c6;
|
||||
|
||||
}
|
||||
|
||||
.el-ic {
|
||||
display: none;
|
||||
i, span {
|
||||
padding: 0 1px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.el-tree-node__content:hover .el-ic {
|
||||
color: #428bca !important;
|
||||
display: inline-block;
|
||||
margin-left: 2px;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.el-tree-node__content:hover {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content :hover {
|
||||
.el-tree-node__expand-icon.is-leaf {
|
||||
color: transparent;
|
||||
cursor: default;
|
||||
}
|
||||
/*background-color: #3998d9;*/
|
||||
.custom-tree-node {
|
||||
font-weight: bold;
|
||||
}
|
||||
.el-tree-node__expand-icon {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
<style lang="scss" />
|
||||
|
||||
96
src/components/mdp-ui-ext/mdp-select-branch/Index.vue
Normal file
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<MdpSelectTable :relative="relative" :initName="initName" :initLoad="initLoad" :label="label" :width="width" :placeholder="placeholder" :show-style="showStyle" ref="select" v-model="myVal" :loadFun="$mdp.listBranch" :props="{id:'id',name:'branchName'}" @change2="(e)=>$emit('change2',e)" @change="(e)=>$emit('change',e)" :multiple="multiple" :split="split" :disabled="disabled" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
computed:{
|
||||
myVal:{
|
||||
set(val){
|
||||
this.$emit('update:modelValue',val)
|
||||
},
|
||||
get(){
|
||||
return this.modelValue
|
||||
}
|
||||
}
|
||||
},
|
||||
name: 'MdpSelectBranch',
|
||||
props:{
|
||||
modelValue:{
|
||||
type: String,Array,
|
||||
default: null
|
||||
},
|
||||
multiple:{
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showStyle:{
|
||||
type:String,
|
||||
default:'origin'
|
||||
},
|
||||
label:{
|
||||
type:String,
|
||||
default: '机构'
|
||||
},
|
||||
placeholder:{
|
||||
type:String,
|
||||
default: '机构'
|
||||
},
|
||||
disabled:{
|
||||
type: Boolean,
|
||||
default:false
|
||||
},
|
||||
width:{
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
split:{
|
||||
type: String,
|
||||
default:null,
|
||||
},
|
||||
/**
|
||||
* 当tag 模式下,定位出问题后,设置此参数可解决问题
|
||||
*/
|
||||
relative:{
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* 初始化时,如果已知名称,用此属性可以反显
|
||||
*/
|
||||
initName:{
|
||||
type: [String,Array],
|
||||
default: null
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化时,initLoad=true将进行远程调用,否则不进行远程调用
|
||||
*/
|
||||
initLoad:{
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
||||
onTableDataSelect(datas){
|
||||
this.$refs['select'].onTableDataSelect(datas)
|
||||
this.$refs['tableDialog'].close();
|
||||
},
|
||||
onTableLoadDatas(res){
|
||||
this.$refs['select'].onTableLoadDatas(res)
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '../../mdp-ui/index.scss';
|
||||
</style>
|
||||
@@ -1,387 +1,291 @@
|
||||
<template>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<el-space wrap>
|
||||
<el-input style="width:100%;" v-model="deptFilterText" placeholder="编号、名称过滤" auto-complete="off" />
|
||||
<el-button type="primary" @click="addTopNode" icon="plus" title="添加一级部门" />
|
||||
<el-button v-if="showConfirm" type="warning" @click="confirm" icon="check" title="确认选择" />
|
||||
|
||||
<MdpTree
|
||||
ref="nodeTree"
|
||||
title="部门"
|
||||
showCheckbox
|
||||
:props="propsCpd"
|
||||
:load="listDept"
|
||||
:del="delDept"
|
||||
:multiple="multiple"
|
||||
:showConfirm="showConfirm"
|
||||
:hidden="hiddenCpd"
|
||||
@addTopNode="(cb) => onAddTopClick(cb)"
|
||||
@editNode="(d, cb, subcb) => onEditClick(d, cb, subcb)"
|
||||
@addSubNode="(p, cb) => onAddSubClick(p, cb)"
|
||||
@changePid="(cks,cb) => onChangePidClick(cks,cb)"
|
||||
@confirm = "(d)=>{$emit('confirm',d);$emit('select',d)}"
|
||||
@check-change="(d,c,i)=>$emit('check-change',d,c,i)"
|
||||
@node-click="(d,n,c)=>$emit('node-click',d,n,c)"
|
||||
rootId="A0"
|
||||
:draggable="true"
|
||||
>
|
||||
<template #nodeName="{ data }">
|
||||
<el-space>
|
||||
<div><Icon v-if="data.icon" :icon="data.icon"/>{{data.deptName}}</div>
|
||||
</el-space>
|
||||
</template>
|
||||
<el-tree v-if="treeVisible" v-loading="listLoading" :props="defaultDeptTreeProps" :filter-node-method="filterDeptNode"
|
||||
:show-checkbox="showCheckbox" :expand-on-click-node="expandOnClickNode" :indent="indent" :node-key="'deptid'"
|
||||
:default-expanded-keys="defaultExpandedKeys" :default-checked-keys="defaultCheckedKeys" auto-expand-parent
|
||||
highlight-current style="min-height:100px;" @check-change="handleCheckChange" @current-change="handleCurrentChange"
|
||||
@node-click="handleNodeClick" :check-on-click-node="true" check-strictly lazy :load="loadNode" ref="deptTree" @contextmenu.prevent >
|
||||
</template>
|
||||
</MdpTree>
|
||||
|
||||
<template #default="{ node, data }">
|
||||
<div class="custom-tree-node" @contextmenu.prevent title="右键可以增删改">
|
||||
<el-popover :open-delay="1000" placement="top-start" :width="showConfirm ? 300 : 200" trigger="contextmenu">
|
||||
|
||||
<el-button icon="plus" circle type="success" v-if="!(!data.deptid || data.deptid == 'A0' || data.deptid == '0')"
|
||||
@click.prevent.stop="addNode(data, node)" title="添加子部门" />
|
||||
<el-button icon="edit" circle type="warning" v-if="!(!data.deptid || data.deptid == 'A0' || data.deptid == '0')"
|
||||
@click.prevent.stop="editNode(data, node)" title="修改部门" />
|
||||
<el-button icon="delete" circle type="danger" v-if="!(!data.deptid || data.deptid == 'A0' || data.deptid == '0')"
|
||||
@click.prevent.stop="deleteNode(data, node)" title="删除该部门" />
|
||||
|
||||
<template #reference>
|
||||
<div style="display:flex;align-items:center;width:100%;"> {{ data.deptName }} </div>
|
||||
</template>
|
||||
</el-popover>
|
||||
</div>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-card>
|
||||
|
||||
<mdp-dialog title="新增部门" ref="addDialog" width="60%" append-to-body>
|
||||
<el-form ref="addDept" :model="addDept" label-width="200">
|
||||
|
||||
<el-form-item label="上级部门">
|
||||
|
||||
<el-tag>{{ currentDept && currentDept.deptid && currentDept.deptid != 'A0' ? currentDept.deptName : "顶级部门A0" }}</el-tag>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item label="部门编号">
|
||||
<el-input v-model="addDept.deptid" placeholder="如果为空,则系统自动生成" />
|
||||
</el-form-item>
|
||||
<el-form-item label="部门名称" prop="deptName" :rules="[
|
||||
{ required: true, message: '名称不能为空' }
|
||||
]">
|
||||
<el-input v-model="addDept.deptName" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="$refs['addDialog'].close()">关闭</el-button>
|
||||
<el-button type="primary" v-loading="addLoading" @click="addDeptSubmit">确 定</el-button>
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
|
||||
<mdp-dialog title="修改部门提示" width="60%" append-to-body ref="editDialog">
|
||||
<el-form ref="editDept" :model="editDept" label-width="200">
|
||||
<el-form-item label="部门编号" prop="id">
|
||||
{{ editDept.deptid }}
|
||||
</el-form-item>
|
||||
<el-form-item label="部门名称" prop="deptName" :rules="[
|
||||
{ required: true, message: '名称不能为空' }
|
||||
<!--编辑 Dept xm_project_func界面-->
|
||||
<mdp-dialog ref="editDialog" width="30%" append-to-body :close-on-click-modal="false">
|
||||
<template #default="{ data,dialog }">
|
||||
<el-form ref="editForm" :model="editForm" label-width="150" >
|
||||
<el-form-item label="部门编号" prop="deptid" :rules="[
|
||||
{ required: true, message: '不能为空'}
|
||||
]">
|
||||
<el-input v-model="editDept.deptName" />
|
||||
</el-form-item>
|
||||
{{editForm.deptid}}
|
||||
</el-form-item>
|
||||
<el-form-item label="部门名称" prop="deptName"
|
||||
:rules="[
|
||||
{ required: true, message: '名称不能为空'}
|
||||
]">
|
||||
<el-input v-model="editForm.deptName" />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="$refs['editDialog'].close()">关 闭</el-button>
|
||||
<el-button type="primary" v-loading="editLoading" @click="editDeptSubmit">确 定</el-button>
|
||||
|
||||
<el-form-item label="图标" >
|
||||
<IconSelect v-model="editForm.icon"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div class="footer">
|
||||
<el-button @click="dialog.close()">关 闭</el-button>
|
||||
<el-button type="primary" v-loading="loading.edit" @click="editSubmit(data.callback)">确 定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
|
||||
<!--新增 Dept xm_project_func界面-->
|
||||
<mdp-dialog ref="addDialog" width="30%" append-to-body :close-on-click-modal="false">
|
||||
<template #default="{ data, dialog }">
|
||||
<el-form ref="addForm" :model="addForm" label-width="150" >
|
||||
|
||||
<el-form-item label="上级部门">
|
||||
|
||||
<el-tag>{{ data.parent && data.parent.deptid && data.parent.deptid!='A0'? "上级:"+data.parent.deptName:"顶级部门A0" }}</el-tag>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item label="部门编号" prop="deptid" :rules="[
|
||||
{ required: true, message: '不能为空'}
|
||||
]">
|
||||
<el-input v-model="addForm.deptid" placeholder="如果为空,则系统自动生成"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="部门名称" prop="deptName"
|
||||
:rules="[
|
||||
{ required: true, message: '名称不能为空'}
|
||||
]">
|
||||
<el-input v-model="addForm.deptName" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="图标" >
|
||||
<IconSelect v-model="addForm.icon"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div class="footer">
|
||||
<el-button @click="dialog.close()">关闭</el-button>
|
||||
<el-button type="primary" v-loading="loading.add" @click="addSubmit(data.parent,data.callback)">确 定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util' //全局公共库
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
|
||||
export default {
|
||||
watch: {
|
||||
deptFilterText(val) {
|
||||
this.$refs.deptTree.filter(val);
|
||||
},
|
||||
checkedKeys(val) {
|
||||
this.$refs.deptTree.setCheckedKeys(val);
|
||||
},
|
||||
refresh(val) {
|
||||
this.getDeptTreeData(val);
|
||||
},
|
||||
currentKey(val) {
|
||||
this.$refs.deptTree.setCheckedKeys([val]);
|
||||
},
|
||||
value(val) {
|
||||
this.deptid = val;
|
||||
},
|
||||
deptid(val) {
|
||||
this.$emit('input', val);
|
||||
},
|
||||
},
|
||||
components: {
|
||||
},
|
||||
computed: {
|
||||
defaultExpandedKeys() {
|
||||
return this.expandRowKeys
|
||||
},
|
||||
defaultCheckedKeys() {
|
||||
if (this.value) {
|
||||
return [this.value];
|
||||
}
|
||||
return this.checkedKeys;
|
||||
},
|
||||
...mapState(useUserStore, [
|
||||
'userInfo'
|
||||
]),
|
||||
},
|
||||
props: {
|
||||
'value': String, Array,
|
||||
'branchId': String,
|
||||
'visible': { type: Boolean, default: false },
|
||||
'showCount': { type: Boolean, default: false },
|
||||
'showRoot': { type: Boolean, default: false },
|
||||
'countTips': String,
|
||||
'showFilter': { type: Boolean, default: false },
|
||||
'multiple': { type: Boolean, default: false },
|
||||
'checkedKeys': Array,
|
||||
'refresh': { type: Boolean, default: false },
|
||||
'defaultExpandAll': { type: Boolean, default: false },
|
||||
'expandOnClickNode': { type: Boolean, default: false },
|
||||
showCheckbox: { type: Boolean, default: false },
|
||||
showConfirm: { type: Boolean, default: false },
|
||||
'indent': Number
|
||||
|
||||
},
|
||||
'subOpType':{type:String,defalut:'mng'},
|
||||
'multiple':{type:Boolean,default:false},
|
||||
'showConfirm':{type:Boolean,default:false},
|
||||
'hidden':{type:Object,default:()=>null},
|
||||
'params':{type:Object,default:()=>null},
|
||||
'clearable':{type:Boolean,default:true},
|
||||
relyType:{
|
||||
type:String,
|
||||
default:''
|
||||
},
|
||||
relyId:{
|
||||
type:String,
|
||||
default:''
|
||||
},
|
||||
relyStype:{
|
||||
type:String,
|
||||
default:'',
|
||||
},
|
||||
relySid:{
|
||||
type:String,
|
||||
default:''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore, ['userInfo', 'roles']),
|
||||
|
||||
hiddenCpd(){
|
||||
var isSelect=this.subOpType=='select'
|
||||
var hidden ={
|
||||
batchDel: isSelect,
|
||||
del:isSelect,
|
||||
changePid: false,
|
||||
addTop: isSelect,
|
||||
addSub: isSelect,
|
||||
edit: isSelect,
|
||||
filter: false,
|
||||
page: true,
|
||||
}
|
||||
hidden=Object.assign(hidden,this.hidden)
|
||||
return hidden
|
||||
},
|
||||
propsCpd(){
|
||||
return { id: 'deptid', pid: 'pdeptid', label: 'deptName' , isLeaf:(data,n)=>{
|
||||
return data.childNum<=0
|
||||
}}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
deptFilterText: '',
|
||||
defaultDeptTreeProps: {
|
||||
id: 'deptid',
|
||||
label: 'deptName',
|
||||
children: 'children',
|
||||
isLeaf: function (n) {
|
||||
return n.childNum <= 0
|
||||
}
|
||||
},
|
||||
listLoading: false,
|
||||
deptid: '',
|
||||
expandRowKeys: [],
|
||||
root: null,
|
||||
resolve: null,
|
||||
filters: {
|
||||
|
||||
addDept:{deptid:'',deptName:'',pdeptid:''},
|
||||
editDept:{deptid:'',deptName:'',pdeptid:''},
|
||||
treeVisible:true,
|
||||
isAddTop: false,
|
||||
currentDept:{},
|
||||
},
|
||||
addForm:{deptid:'',pdeptid:'',deptName:'',isLeaf:'0',isAuth:'0',limitType:'2',deptType:'',pqx:'',qxLvl:''},
|
||||
editForm:{deptid:'',pdeptid:'',deptName:'',isLeaf:'0',isAuth:'0',limitType:'2',deptType:'',pqx:'',qxLvl:''},
|
||||
loading:{add:false,edit:false,list:false}
|
||||
}
|
||||
},
|
||||
}, //end data
|
||||
methods: {
|
||||
addDeptSubmit(){
|
||||
var branchId=this.userInfo.branchId
|
||||
var pdeptid=""
|
||||
if(this.isAddTop){
|
||||
pdeptid="A0"
|
||||
}else{
|
||||
pdeptid=this.currentDept.deptid
|
||||
branchId=this.currentDept.branchId||this.userInfo.branchId
|
||||
}
|
||||
this.addDept.pdeptid=pdeptid
|
||||
this.addDept.branchId=branchId
|
||||
this.$refs.addDept.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$confirm('确认提交吗?', '提示', {}).then(() => {
|
||||
this.addLoading = true;
|
||||
this.$mdp.addDept(this.addDept).then(res=>{
|
||||
this.addLoading=false;
|
||||
if(res.tips.isOk){
|
||||
|
||||
|
||||
this.$message.success(res.tips.msg);
|
||||
if(!this.isAddTop){
|
||||
if(this.currentDept.children){
|
||||
this.currentDept.children.push(res.data)
|
||||
}else{
|
||||
this.currentDept.children=[res.data]
|
||||
}
|
||||
}else{
|
||||
this.$refs['deptTree'].append(res.data,this.root)
|
||||
}
|
||||
}else{
|
||||
this.$message.error(res.tips.msg);
|
||||
}
|
||||
}).catch(e=>this.addLoading = false );
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
editDeptSubmit(){
|
||||
this.$refs.editDept.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$confirm('确认提交吗?', '提示', {}).then(() => {
|
||||
this.editLoading = true;
|
||||
this.$mdp.editDept(this.editDept).then(res=>{
|
||||
//console.log("res--"+JSON.stringify(res));
|
||||
this.editLoading = false;
|
||||
if(res.tips.isOk){
|
||||
this.$message.success(res.tips.msg);
|
||||
|
||||
this.$refs['deptTree'].updateKeyChildren(res.data.deptid,res.data)
|
||||
this.editVisible=false
|
||||
}else{
|
||||
this.$message.error(res.tips.msg);
|
||||
}
|
||||
}).catch(e=>this.editLoading = false );
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
addTopNode(){
|
||||
this.isAddTop=true
|
||||
this.addDept.pdeptid='A0'
|
||||
this.addDept.deptid=''
|
||||
this.addDept.deptName=''
|
||||
this.$refs['addDialog'].open()
|
||||
},
|
||||
addNode(data, node, comp) {
|
||||
this.isAddTop=false
|
||||
this.currentDept=data
|
||||
|
||||
this.addDept.pdeptid=data.deptid
|
||||
this.addDept.deptid=''
|
||||
this.addDept.deptName=''
|
||||
this.$refs['addDialog'].open()
|
||||
},
|
||||
editNode(data, node, comp) {
|
||||
this.editDept=data
|
||||
this.$refs['editDialog'].open()
|
||||
},
|
||||
deleteNode(data, node, comp) {
|
||||
if(data.childNum>0||data.children?.length>0){
|
||||
this.$message.error("请先删除子元素");
|
||||
return;
|
||||
}
|
||||
let params={
|
||||
deptid:data.deptid
|
||||
}
|
||||
this.$confirm('确认删除吗?', '提示', {}).then(() => {
|
||||
this.$mdp.delDept(params).then(res=>{
|
||||
//console.log("res--"+JSON.stringify(res));
|
||||
if(res.tips.isOk){
|
||||
this.$refs['deptTree'].remove(data)
|
||||
this.$message.success(res.tips.msg);
|
||||
}else{
|
||||
this.$message.error(res.tips.msg);
|
||||
}
|
||||
});
|
||||
})
|
||||
return false;
|
||||
},
|
||||
handleCheckChange(data, checked, indeterminate) {
|
||||
let checkedKeys = this.$refs.deptTree.getCheckedKeys();
|
||||
|
||||
if (this.multiple === undefined || this.multiple === false || this.multiple === 'false') {
|
||||
if (checked == true) {
|
||||
if (checkedKeys.length > 1) {
|
||||
this.$refs.deptTree.setCheckedKeys([data['deptid']]);
|
||||
this.$emit('check-change', data, checked, indeterminate);
|
||||
this.deptid = data['deptid'];
|
||||
} else {
|
||||
this.$emit('check-change', data, checked, indeterminate);
|
||||
this.deptid = data['deptid'];
|
||||
}
|
||||
} else {
|
||||
if (checkedKeys.length == 0) {
|
||||
this.deptid = '';
|
||||
this.$emit('check-change', data, checked, indeterminate);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.$emit('check-change', data, checked, indeterminate);
|
||||
}
|
||||
listDept(params, node) {
|
||||
Object.assign(params,this.filters)
|
||||
if(this.params){
|
||||
Object.assign(params,this.params)
|
||||
}
|
||||
return this.$mdp.listDept(params)
|
||||
},
|
||||
handleCurrentChange(data, node) {
|
||||
this.$emit('current-change', data, node);
|
||||
},
|
||||
handleNodeClick(data, node, comp) {
|
||||
this.$emit('node-click', data, node, comp);
|
||||
},
|
||||
translateDataToTree(data) {
|
||||
if (!data) {
|
||||
return [];
|
||||
}
|
||||
return data
|
||||
},
|
||||
//获取部门树列表
|
||||
getDeptTreeData(refresh) {
|
||||
this.treeVisible=false
|
||||
this.$nextTick(()=>{
|
||||
this.treeVisible=true
|
||||
delDept(p){return this.$mdp.delDept(p)},
|
||||
|
||||
addDept(p){return this.$mdp.addDept(p)},
|
||||
|
||||
editDept(p){return this.$mdp.editDept(p)},
|
||||
batchChangeParent(p){return this.$mdp.batchChangeDeptParent(p)},
|
||||
//显示编辑界面 Dept xm_project_func
|
||||
onEditClick: function (formData, callback, addSubCallback) {
|
||||
this.editForm={...formData}
|
||||
this.$refs['editDialog'].open({
|
||||
formData: formData,
|
||||
callback: callback,
|
||||
addSubCallback: addSubCallback
|
||||
})
|
||||
},
|
||||
filterDeptNode(value, data) {
|
||||
if (!value) return true;
|
||||
if (data.deptid.indexOf(value) >= 0 || data.deptName.indexOf(value) >= 0) {
|
||||
return true;
|
||||
} else {
|
||||
if (data.pdeptid && data.pdeptid.indexOf(value) >= 0) {
|
||||
return true;
|
||||
}
|
||||
//显示新增界面 Dept xm_project_func
|
||||
onAddTopClick: function (callback) {
|
||||
var formData = {}
|
||||
if (!this.initExtParams(formData)) {
|
||||
return
|
||||
}
|
||||
return false;
|
||||
},
|
||||
confirm() {
|
||||
var nodes = this.$refs.deptTree.getCheckedNodes(false, false)
|
||||
if (this.multiple) {
|
||||
this.$emit('confirm', nodes)
|
||||
} else {
|
||||
this.$emit('confirm', nodes && nodes.length > 0 ? nodes[0] : null)
|
||||
}
|
||||
|
||||
|
||||
this.$refs['addDialog'].open({
|
||||
formData: formData,
|
||||
parent: null,
|
||||
callback: callback
|
||||
})
|
||||
},
|
||||
loadNode(node, resolve) {
|
||||
if (node.level === 0) {
|
||||
this.root = node
|
||||
this.resolve = resolve
|
||||
let params = {
|
||||
'res.levelType': 'L1'
|
||||
};
|
||||
params.branchId = this.branchId
|
||||
if (params.branchId == null || params.branchId == '') {
|
||||
params.branchId = this.userInfo.branchId
|
||||
}
|
||||
this.listLoading = true;
|
||||
this.$mdp.listDept(params).then((res) => {
|
||||
var tips = res.tips;
|
||||
var data = res.data;
|
||||
this.listLoading = false;
|
||||
var tempData = this.translateDataToTree(data);
|
||||
this.expandRowKeys = tempData?.length > 0 ? [tempData[0]] : []
|
||||
resolve(tempData)
|
||||
|
||||
}).catch(() => {
|
||||
this.listLoading = false;
|
||||
});
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
let params = {
|
||||
pdeptid: node.data.deptid
|
||||
};
|
||||
if (params.branchId == null || params.branchId == '') {
|
||||
params.branchId = this.userInfo.branchId
|
||||
initExtParams(formData, parent) {
|
||||
return true
|
||||
},
|
||||
onAddSubClick: function (parent, callback) {
|
||||
var formData = {}
|
||||
if (!this.initExtParams(formData, parent)) {
|
||||
return
|
||||
}
|
||||
Object.assign(formData,parent)
|
||||
formData.pdeptid=parent.deptid
|
||||
formData.deptid=null
|
||||
this.addForm={...formData}
|
||||
this.$refs['addDialog'].open({
|
||||
formData: formData,
|
||||
parent: parent,
|
||||
callback: callback
|
||||
})
|
||||
},
|
||||
onChangePidClick: function(idLinks,callback){
|
||||
this.batchChangeParent(idLinks).then(res=>{
|
||||
let {tips}=res
|
||||
if(tips.isOk){
|
||||
if(callback){
|
||||
callback(true)
|
||||
}
|
||||
this.$message.success(tips.msg)
|
||||
}else{
|
||||
this.$message.error(tips.msg)
|
||||
}
|
||||
this.listLoading = true;
|
||||
this.$mdp.listDept(params).then((res) => {
|
||||
var tips = res.tips;
|
||||
var data = res.data;
|
||||
this.listLoading = false;
|
||||
resolve(this.translateDataToTree(data))
|
||||
})
|
||||
},
|
||||
addSubmit(parent,callback){
|
||||
var branchId=this.userInfo.branchId
|
||||
|
||||
this.addForm.branchId=branchId
|
||||
if(this.relyType){
|
||||
this.addForm.relyType=this.relyType
|
||||
}
|
||||
|
||||
if(this.relyId){
|
||||
this.addForm.relyId=this.relyId
|
||||
}
|
||||
|
||||
if(this.relyStype){
|
||||
this.addForm.relyStype=this.relyStype
|
||||
}
|
||||
|
||||
if(this.relySid){
|
||||
this.addForm.relySid=this.relySid
|
||||
}
|
||||
this.$refs.addForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$confirm('确认提交吗?', '提示', {}).then(() => {
|
||||
this.loading.add = true;
|
||||
this.addDept(this.addForm).then(res=>{
|
||||
this.loading.add=false;
|
||||
if(res.tips.isOk){
|
||||
this.$message.success(res.tips.msg);
|
||||
this.$refs.addDialog.close()
|
||||
callback(res.data)
|
||||
}else{
|
||||
this.$message.error(res.tips.msg);
|
||||
}
|
||||
}).catch(e=>this.loading.add = false );
|
||||
|
||||
}).catch(() => {
|
||||
this.listLoading = false;
|
||||
});
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
editSubmit(callback){
|
||||
this.$refs.editForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$confirm('确认提交吗?', '提示', {}).then(() => {
|
||||
this.loading.edit = true;
|
||||
this.editDept(this.editForm).then(res=>{
|
||||
if(res.tips.isOk){
|
||||
this.loading.edit = false
|
||||
this.$refs.editDialog.close();
|
||||
this.$message.success(res.tips.msg);
|
||||
callback(this.editForm)
|
||||
}else{
|
||||
this.$message.error(res.tips.msg);
|
||||
}
|
||||
}).catch(e=>this.loading.edit = false );
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}, //end methods
|
||||
components: {
|
||||
},
|
||||
mounted() {
|
||||
this.deptid = this.value;
|
||||
//this.getDeptTreeData();
|
||||
mounted() {
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
|
||||
|
||||
<style lang="scss" />
|
||||
|
||||
@@ -72,6 +72,18 @@ export default {
|
||||
getDate() {
|
||||
return moment().format(DEFAULT_PATTERN)
|
||||
},
|
||||
//获取两个日期之间的月份列表
|
||||
getMonths(startDate, endDate) {
|
||||
let months = [];
|
||||
let current = moment(startDate);
|
||||
|
||||
while (current.isBefore(endDate)) {
|
||||
months.push(current.clone());
|
||||
current.add(1, 'months');
|
||||
}
|
||||
|
||||
return months;
|
||||
},
|
||||
|
||||
getQueryStringByName: function(name) {
|
||||
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
|
||||
@@ -136,6 +148,16 @@ export default {
|
||||
toMLine(name) {
|
||||
return name.replace(/([A-Z])/g, "-$1").toLowerCase();
|
||||
},
|
||||
toFixed(val,scale){
|
||||
if(!val){
|
||||
return 0
|
||||
}else{
|
||||
return val.toFixed(scale)
|
||||
}
|
||||
},
|
||||
moment:function(){
|
||||
return moment()
|
||||
},
|
||||
|
||||
formatDate: function(date, pattern) {
|
||||
if(!date){
|
||||
|
||||
@@ -10,19 +10,28 @@
|
||||
<el-input v-if="!hiddenCpd.filter" style="width:10em;" v-model="filterText" placeholder="名称" auto-complete="off" clearable/>
|
||||
<el-button v-if="!hiddenCpd.addTop" type="primary" @click="addTopNode_()" icon="plus" :title="'添加一级' + title" plain/>
|
||||
<el-button v-if="!hiddenCpd.batchDel" type="danger" @click="batchDel_()" icon="delete" :title="'批量删除'" plain/>
|
||||
<el-button v-if="!hiddenCpd.changePid" type="warning" @click="changePid_()" icon="top" :title="'调整上级'" plain/>
|
||||
|
||||
</slot>
|
||||
<el-button v-if="showConfirm" type="warning" @click="confirm" icon="check" title="确认选择" />
|
||||
<el-button v-if="!hiddenCpd.changePid && idLinks.size>0" type="warning" @click="changePid_()" icon="top" :title="'拖拽后必须保存才能正式生效'">拖拽后保存</el-button>
|
||||
<el-button v-if="!hiddenCpd.changePid && idLinks.size>0" @click="cancelChangePid()" icon="close" :title="'取消保存'">取消</el-button>
|
||||
|
||||
</slot>
|
||||
<el-button v-if="showConfirm" type="warning" @click="confirm" icon="check" title="确认选择" />
|
||||
</el-space>
|
||||
</template>
|
||||
<el-tree v-adaptive style="width:100%;" v-if="treeVisible" v-loading="listLoading" :props="propsCpd" :filter-node-method="filterNode"
|
||||
:show-checkbox="showCheckbox" :expand-on-click-node="expandOnClickNode" :indent="indent" :node-key="propsCpd['id']"
|
||||
<el-tree v-adaptive style="width:100%;" v-if="treeVisible" v-loading="loading.addlist" :props="propsCpd" :filter-node-method="filterNode"
|
||||
:show-checkbox="showCheckbox" :expand-on-click-node="expandOnClickNode" :indent="indent" :node-key="propsCpd.id"
|
||||
:default-expanded-keys="defaultExpandedKeys" :default-checked-keys="defaultCheckedKeys" auto-expand-parent
|
||||
highlight-current @check-change="handleCheckChange" @current-change="handleCurrentChange" accordion
|
||||
@node-click="handleNodeClick" :check-on-click-node="true" check-strictly lazy :load="loadNode" ref="nodeTree"
|
||||
@contextmenu.prevent>
|
||||
@contextmenu.prevent
|
||||
:draggable="draggable"
|
||||
@node-drag-start="handleDragStart"
|
||||
@node-drag-enter="handleDragEnter"
|
||||
@node-drag-leave="handleDragLeave"
|
||||
@node-drag-over="handleDragOver"
|
||||
@node-drag-end="handleDragEnd"
|
||||
@node-drop="handleDrop"
|
||||
:allowDrop="myAllowDrop"
|
||||
>
|
||||
|
||||
<template #default="{ node, data }">
|
||||
<div class="custom-tree-node" @contextmenu.prevent title="右键可以增删改">
|
||||
@@ -34,7 +43,7 @@
|
||||
@click.prevent.stop="editNode_(data, node)" :title="'修改' + title" />
|
||||
<el-button icon="delete" circle type="danger" v-if="!(!data[propsCpd['id']] || data[propsCpd['id']] == rootId) && !hiddenCpd.del"
|
||||
@click.prevent.stop="deleteNode_(data, node)" :title="'删除该' + title" />
|
||||
<slot name="nodeToolbar">
|
||||
<slot name="nodeToolbar" :data="data" :node="node">
|
||||
|
||||
</slot>
|
||||
</slot>
|
||||
@@ -105,6 +114,8 @@ export default {
|
||||
}
|
||||
},
|
||||
props: {
|
||||
'allowDrop':{type: Function,default:null},
|
||||
'draggable':{type: Boolean,default: false},
|
||||
'showCount': { type: Boolean, default: false },
|
||||
'showFilter': { type: Boolean, default: false },
|
||||
'multiple': { type: Boolean, default: false },
|
||||
@@ -128,7 +139,7 @@ export default {
|
||||
label: 'name',
|
||||
pid: 'pid',
|
||||
children: 'children',
|
||||
isLeaf: function (n) {
|
||||
isLeaf: function (n,node) {
|
||||
return n.childNum <= 0
|
||||
}
|
||||
}
|
||||
@@ -163,8 +174,10 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filterText: '',
|
||||
listLoading: false,
|
||||
idLinks:new Map(),//存储新的上下级关系,key=id,value=pid
|
||||
oldIdLinks: new Map(), //存储原来的上下级关系,key=id,value=pid,只存一次,拖拽开始的时候就存入
|
||||
draging: false,//拖拽成功后变成true,保存后变成false
|
||||
filterText: '',
|
||||
expandRowKeys: [],
|
||||
root: null,
|
||||
resolve: null,
|
||||
@@ -176,10 +189,69 @@ export default {
|
||||
pageSize: 500,
|
||||
pageNum: 1,
|
||||
count: true
|
||||
}
|
||||
},
|
||||
loading:{add:false,edit:false,list:false,del:false}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleDragStart(node,event){
|
||||
|
||||
this.$emit("node-drag-start",node,event)
|
||||
},
|
||||
|
||||
handleDragEnter(draggingNode,dropNode,event){
|
||||
this.$emit("node-drag-enter",draggingNode,dropNode,event)
|
||||
},
|
||||
|
||||
handleDragLeave(draggingNode,dropNode,event){
|
||||
|
||||
this.$emit("node-drag-leave",draggingNode,dropNode,event)
|
||||
},
|
||||
|
||||
handleDragOver(draggingNode,dropNode,event){
|
||||
|
||||
this.$emit("node-drag-over",draggingNode,dropNode,event)
|
||||
|
||||
},
|
||||
|
||||
handleDragEnd(draggingNode,dropNode,dropType,event){
|
||||
|
||||
this.$emit("node-drag-end",draggingNode,dropNode,dropType,event)
|
||||
},
|
||||
|
||||
myAllowDrop(draggingNode,dropNode,dropType){
|
||||
return this.allowDrop?this.allowDrop(draggingNode,dropNode,dropType):true
|
||||
},
|
||||
handleDrop(draggingNode,dropNode,dropType,event){
|
||||
this.draging=true
|
||||
let idKey=this.propsCpd['id']
|
||||
let pidKey=this.propsCpd['pid']
|
||||
let sdata=draggingNode.data
|
||||
var pnode=dropNode
|
||||
if(dropType!='inner'){
|
||||
pnode=dropNode.parent
|
||||
}
|
||||
let edata=pnode.data
|
||||
let oldPid=sdata[pidKey]
|
||||
let newPid=edata[idKey]
|
||||
if(newPid==oldPid){
|
||||
this.idLinks.delete(sdata[idKey])
|
||||
}else{
|
||||
this.idLinks.set(sdata[idKey],edata[idKey])
|
||||
}
|
||||
if(!pnode.expanded ){
|
||||
var callback=null;
|
||||
if(pnode.shouldLoadData()){
|
||||
callback=()=>{
|
||||
//加载数据后需要手动添加一个节点,bug
|
||||
pnode.insertChild({data:sdata})
|
||||
}
|
||||
}
|
||||
pnode.expand(callback)
|
||||
}
|
||||
this.$emit("node-drop",draggingNode,dropNode,dropType,event)
|
||||
|
||||
},
|
||||
getCheckedKeys(){
|
||||
return this.$refs.nodeTree.getCheckedKeys();
|
||||
},
|
||||
@@ -188,6 +260,7 @@ export default {
|
||||
return this.$refs.nodeTree.getCheckedNodes()
|
||||
},
|
||||
updateKeyChildren(key,data){
|
||||
debugger
|
||||
this.$refs['nodeTree'].updateKeyChildren(key,data)
|
||||
},
|
||||
addTopNode(data){
|
||||
@@ -203,11 +276,14 @@ export default {
|
||||
if(!data){
|
||||
return
|
||||
}
|
||||
if(parent.children){
|
||||
parent.children.push(data)
|
||||
debugger
|
||||
var pnode=this.$refs.nodeTree.getNode(parent[this.propsCpd['id']])
|
||||
if(!pnode.expanded ){
|
||||
pnode.expand()
|
||||
}else{
|
||||
parent.children=[data]
|
||||
pnode.insertChild({data:data})
|
||||
}
|
||||
|
||||
},
|
||||
addSubNode_(parent, node, comp) {
|
||||
|
||||
@@ -217,11 +293,13 @@ export default {
|
||||
this.$emit('addSubNode',parent,callback)
|
||||
},
|
||||
editNode_(cdata, node, comp) {
|
||||
|
||||
var callback = (data) => {
|
||||
debugger
|
||||
if(!data){
|
||||
return
|
||||
}
|
||||
this.$refs['nodeTree'].updateKeyChildren(cdata[this.propsCpd['id']],data)
|
||||
Object.assign(node.data,data)
|
||||
}
|
||||
var addSubCallback = (subData) => {
|
||||
this.addSubNode(cdata,subData)
|
||||
@@ -248,16 +326,26 @@ export default {
|
||||
})
|
||||
return false;
|
||||
},
|
||||
changePid_(){
|
||||
let checkedKeys = this.$refs.nodeTree.getCheckedKeys();
|
||||
if(checkedKeys.length==0){
|
||||
this.$message.error("请选择需要更换上级的记录");
|
||||
cancelChangePid(){
|
||||
this.refresh()
|
||||
},
|
||||
changePid_(){
|
||||
if(this.idLinks.length==0){
|
||||
this.$message.error("没有数据改变,无须保存");
|
||||
return;
|
||||
}
|
||||
var callback = () => {
|
||||
this.refresh()
|
||||
var callback = (refresh) => {
|
||||
this.idLinks=new Map()
|
||||
if(refresh)this.refresh()
|
||||
}
|
||||
this.$emit('changePid',checkedKeys,callback)
|
||||
var list=[]
|
||||
this.idLinks.forEach((value, key) => {
|
||||
let d={}
|
||||
d[this.propsCpd['id']]=key
|
||||
d[this.propsCpd['pid']]=value
|
||||
list.push(d)
|
||||
});
|
||||
this.$emit('changePid',list,callback)
|
||||
},
|
||||
batchDel_() {
|
||||
let checkedKeys = this.$refs.nodeTree.getCheckedKeys();
|
||||
@@ -317,6 +405,7 @@ export default {
|
||||
},
|
||||
//重新获取部门树列表
|
||||
refresh() {
|
||||
this.idLinks=new Map()
|
||||
this.treeVisible = false
|
||||
this.$nextTick(() => {
|
||||
this.treeVisible = true
|
||||
@@ -351,31 +440,30 @@ export default {
|
||||
this.resolve = resolve
|
||||
let params = {};
|
||||
params[this.propsCpd['pid']] = this.rootId
|
||||
this.listLoading = true;
|
||||
this.loading.addlist = true;
|
||||
this.load(params, node, resolve).then((res) => {
|
||||
var tips = res.tips;
|
||||
var data = res.data;
|
||||
this.listLoading = false;
|
||||
var tempData = this.translateDataToTree(data);
|
||||
//this.expandRowKeys = tempData?.length > 0 ? [tempData[0]] : []
|
||||
this.loading.addlist = false;
|
||||
var tempData = this.translateDataToTree(data);
|
||||
resolve(tempData)
|
||||
|
||||
}).catch(() => {
|
||||
this.listLoading = false;
|
||||
this.loading.addlist = false;
|
||||
});
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
let params = {};
|
||||
params[this.propsCpd['pid']] = node.data[this.propsCpd['id']]
|
||||
this.listLoading = true;
|
||||
this.loading.addlist = true;
|
||||
this.load(params, node, resolve).then((res) => {
|
||||
var tips = res.tips;
|
||||
var data = res.data;
|
||||
this.listLoading = false;
|
||||
this.loading.addlist = false;
|
||||
resolve(this.translateDataToTree(data))
|
||||
|
||||
}).catch(() => {
|
||||
this.listLoading = false;
|
||||
this.loading.addlist = false;
|
||||
});
|
||||
}, 500);
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ export const MdpSelectMixin = {
|
||||
return util.getCodeKey(this.itemCode,this.params)
|
||||
}else{
|
||||
|
||||
if(this.loadFun){
|
||||
if(this.loadFun){
|
||||
return util.getCodeKey(this.loadFun.name,this.params)
|
||||
}else{
|
||||
return "xxxx"
|
||||
@@ -211,10 +211,12 @@ export const MdpSelectMixin = {
|
||||
}
|
||||
this.myValCpd=this.myVal
|
||||
},
|
||||
codeKey(){
|
||||
this.initMyValByValue();
|
||||
codeKey(){
|
||||
this.initItemOptions();
|
||||
},
|
||||
initName(){
|
||||
this.initMyValByValue()
|
||||
}
|
||||
},
|
||||
props: {
|
||||
title:{
|
||||
@@ -735,6 +737,7 @@ export const MdpSelectMixin = {
|
||||
* @returns
|
||||
*/
|
||||
initMyValByValue(){
|
||||
debugger
|
||||
if(this.initOptions && this.initOptions.length>0){
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -689,6 +689,12 @@ export const MdpTableMixin = {
|
||||
form=this.$refs['formDialog']
|
||||
}
|
||||
}
|
||||
if(!form){
|
||||
form=this.$refs['formDlg']
|
||||
if(!form){
|
||||
form=this.$refs['formDlg']
|
||||
}
|
||||
}
|
||||
if(form){
|
||||
if(!parentOpType){
|
||||
parentOpType=this.currOpType
|
||||
@@ -761,11 +767,14 @@ export const MdpTableMixin = {
|
||||
},
|
||||
//即将作废
|
||||
showAdd(){
|
||||
|
||||
this.addFormVisible=true
|
||||
},
|
||||
//即将作废
|
||||
showEdit(){
|
||||
|
||||
showEdit(row){
|
||||
if(row){
|
||||
this.editForm=row
|
||||
}
|
||||
this.editFormVisible=true
|
||||
},
|
||||
//即将作废
|
||||
showDetail(){
|
||||
|
||||
@@ -262,18 +262,7 @@ const RoutesXmCore: AppRouteRecordRaw[] = [
|
||||
roles: ['user'],
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'contract',
|
||||
component: () => import('@/views/xm/pro/xmContract/XmContractForProject.vue'),
|
||||
name: 'projectContract',
|
||||
meta: {
|
||||
title: '项目-合同',
|
||||
icon: 'project',
|
||||
roles: ['user'],
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'record',
|
||||
component: () => import('@/views/xm/core/xmRecord/XmRecordForProject.vue'),
|
||||
@@ -284,51 +273,18 @@ const RoutesXmCore: AppRouteRecordRaw[] = [
|
||||
roles: ['user'],
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'budget',
|
||||
component: () => import('@/views/xm/pro/fin/XmProjectBudgetCost.vue'),
|
||||
name: 'projectBudget',
|
||||
meta: {
|
||||
title: '项目-预算',
|
||||
icon: 'project',
|
||||
roles: ['user'],
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'cost',
|
||||
component: () => import('@/views/xm/pro/fin/XmProjectCost.vue'),
|
||||
name: 'projectCost',
|
||||
meta: {
|
||||
title: '项目-费用',
|
||||
icon: 'project',
|
||||
roles: ['user'],
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'workloadDay',
|
||||
component: () => import('@/views/xm/core/xmWorkload/WorkloadSetDayList.vue'),
|
||||
name: 'projectBudget',
|
||||
name: 'projectWorkloadDay',
|
||||
meta: {
|
||||
title: '项目-工时日报',
|
||||
icon: 'project',
|
||||
roles: ['user'],
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'workloadMonth',
|
||||
component: () => import('@/views/xm/pro/rpt/workload/WorkloadSetMonthList.vue'),
|
||||
name: 'projectWorkloadMonth',
|
||||
meta: {
|
||||
title: '项目-工时月报',
|
||||
icon: 'project',
|
||||
roles: ['user'],
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'file',
|
||||
component: () => import('@/views/xm/core/xmFile/XmFileForProject.vue'),
|
||||
@@ -339,18 +295,7 @@ const RoutesXmCore: AppRouteRecordRaw[] = [
|
||||
roles: ['user'],
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'rpt',
|
||||
component: () => import('@/views/xm/pro/rpt/index/indexForProject.vue'),
|
||||
name: 'projectRpt',
|
||||
meta: {
|
||||
title: '项目-效能',
|
||||
icon: 'project',
|
||||
roles: ['user'],
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -473,17 +418,7 @@ const RoutesXmCore: AppRouteRecordRaw[] = [
|
||||
icon: 'product',
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'contract',
|
||||
component: () => import('@/views/xm/pro/xmContract/XmContractForProduct.vue'),
|
||||
name: 'productContract',
|
||||
meta: {
|
||||
title: '产品-合同',
|
||||
icon: 'product',
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'record',
|
||||
component: () => import('@/views/xm/core/xmRecord/XmRecordForProduct.vue'),
|
||||
@@ -493,27 +428,7 @@ const RoutesXmCore: AppRouteRecordRaw[] = [
|
||||
icon: 'product',
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'workloadDay',
|
||||
component: () => import('@/views/xm/core/xmWorkload/WorkloadSetDayList.vue'),
|
||||
name: 'productBudget',
|
||||
meta: {
|
||||
title: '产品-工时日报',
|
||||
icon: 'product',
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'workloadMonth',
|
||||
component: () => import('@/views/xm/pro/rpt/workload/WorkloadSetMonthList.vue'),
|
||||
name: 'productWorkloadMonth',
|
||||
meta: {
|
||||
title: '产品-工时月报',
|
||||
icon: 'product',
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'file',
|
||||
component: () => import('@/views/xm/core/xmFile/XmFileForProduct.vue'),
|
||||
@@ -525,15 +440,15 @@ const RoutesXmCore: AppRouteRecordRaw[] = [
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'rpt',
|
||||
component: () => import('@/views/xm/pro/rpt/index/indexForProduct.vue'),
|
||||
name: 'productRpt',
|
||||
path: 'workloadDay',
|
||||
component: () => import('@/views/xm/core/xmWorkload/WorkloadSetDayList.vue'),
|
||||
name: 'productWorkloadDay',
|
||||
meta: {
|
||||
title: '产品-效能',
|
||||
title: '产品-工时日报',
|
||||
icon: 'product',
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
@@ -638,33 +553,13 @@ const RoutesXmCore: AppRouteRecordRaw[] = [
|
||||
{
|
||||
path: 'workloadDay',
|
||||
component: () => import('@/views/xm/core/xmWorkload/WorkloadSetDayList.vue'),
|
||||
name: 'iterationBudget',
|
||||
name: 'iterationWorkloadDay',
|
||||
meta: {
|
||||
title: '迭代-工时日报',
|
||||
icon: 'iteration',
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'workloadMonth',
|
||||
component: () => import('@/views/xm/pro/rpt/workload/WorkloadSetMonthList.vue'),
|
||||
name: 'iterationWorkloadMonth',
|
||||
meta: {
|
||||
title: '迭代-工时月报',
|
||||
icon: 'iteration',
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'rpt',
|
||||
component: () => import('@/views/xm/pro/rpt/index/indexForIteration.vue'),
|
||||
name: 'iterationRpt',
|
||||
meta: {
|
||||
title: '迭代-效能',
|
||||
icon: 'iteration',
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -757,13 +652,7 @@ const RoutesXmCore: AppRouteRecordRaw[] = [
|
||||
component: () => import('@/views/xm/core/xmGroup/XmGroupForTest.vue'),
|
||||
name: 'testGroup',
|
||||
meta: { title: '团队', roles: ['user'], hidden: true }
|
||||
},
|
||||
{
|
||||
path: 'rpt',
|
||||
component: () => import('@/views/xm/pro/rpt/index/indexForTest.vue'),
|
||||
name: 'testRpt',
|
||||
meta: { title: '统计分析', roles: ['user'], hidden: true }
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { Layout } from '@/utils/routerHelper'
|
||||
|
||||
import XmProjectLayout from '@/views/xm/core/xmProject/index.vue'
|
||||
import XmProductLayout from '@/views/xm/core/xmProduct/index.vue'
|
||||
import XmIterationLayout from '@/views/xm/core/xmIteration/index.vue'
|
||||
import XmTestLayout from '@/views/xm/core/xmTestCasedb/index.vue'
|
||||
const { t } = useI18n()
|
||||
|
||||
const RoutesXmCore: AppRouteRecordRaw[] = [
|
||||
@@ -45,17 +49,29 @@ const RoutesXmCore: AppRouteRecordRaw[] = [
|
||||
children: [
|
||||
{
|
||||
path: 'branch/cost',
|
||||
component: () => import('@/views/xm/pro/fin/XmProjectCost.vue'),
|
||||
component: () => import('@/views/xm/pro/fin/XmCost.vue'),
|
||||
name: 'XmBranchCost',
|
||||
meta: { title: '应付统计', roles: ['user'] }
|
||||
meta: { title: '成本分析', roles: ['user'] }
|
||||
},
|
||||
|
||||
{
|
||||
path: 'branch/cost/nlabor',
|
||||
component: () => import('@/views/xm/pro/xmCostNlabor/XmCostNlaborMng.vue'),
|
||||
name: 'XmBranchCostNlabor',
|
||||
meta: { title: '支出明细', roles: ['user'] }
|
||||
path: 'branch/cost/record',
|
||||
component: () => import('@/views/xm/pro/xmCostRecord/Index.vue'),
|
||||
name: 'XmBranchCostRecord',
|
||||
meta: { title: '成本明细', roles: ['user'] }
|
||||
},
|
||||
{
|
||||
path: 'branch/budget',
|
||||
component: () => import('@/views/xm/pro/fin/XmBudgetCost.vue'),
|
||||
name: 'XmBranchBudget',
|
||||
meta: { title: '预算分析', roles: ['user'] }
|
||||
},
|
||||
|
||||
{
|
||||
path: 'branch/budget/record',
|
||||
component: () => import('@/views/xm/pro/xmBudgetRecord/Index.vue'),
|
||||
name: 'XmBranchBudgetRecord',
|
||||
meta: { title: '预算明细', roles: ['user'] }
|
||||
},
|
||||
{
|
||||
path: 'task/sbill',
|
||||
component: () => import('@/views/xm/pro/xmTaskSbill/XmTaskSbillMng.vue'),
|
||||
@@ -116,9 +132,189 @@ const RoutesXmCore: AppRouteRecordRaw[] = [
|
||||
component: () => import('@/views/xm/pro/rpt/index/index.vue'),
|
||||
name: 'rptIndex',
|
||||
meta: { title: '指标分析', roles: ['user'] }
|
||||
},
|
||||
{
|
||||
path: 'branch',
|
||||
component: () => import('@/views/xm/pro/XmOverview.vue'),
|
||||
name: 'branchRpt',
|
||||
meta: { title: '企业级效能概览', roles: ['user'] }
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: '/xm/pro/project/view',
|
||||
component: XmProjectLayout,
|
||||
name: 'XmProProjectView',
|
||||
meta: {
|
||||
title: '项目管理',
|
||||
icon: 'project',
|
||||
hidden: true,
|
||||
},
|
||||
// leaf: true,//只有一个节点
|
||||
children: [
|
||||
{
|
||||
path: 'budget',
|
||||
component: () => import('@/views/xm/pro/fin/XmBudgetForProject.vue'),
|
||||
name: 'projectBudget',
|
||||
meta: {
|
||||
title: '项目-预算',
|
||||
icon: 'project',
|
||||
roles: ['user'],
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'cost',
|
||||
component: () => import('@/views/xm/pro/fin/XmCostForProject.vue'),
|
||||
name: 'projectCost',
|
||||
meta: {
|
||||
title: '项目-费用',
|
||||
icon: 'project',
|
||||
roles: ['user'],
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'workloadMonth',
|
||||
component: () => import('@/views/xm/pro/rpt/workload/WorkloadSetMonthList.vue'),
|
||||
name: 'projectWorkloadMonth',
|
||||
meta: {
|
||||
title: '项目-工时月报',
|
||||
icon: 'project',
|
||||
roles: ['user'],
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'rpt',
|
||||
component: () => import('@/views/xm/pro/rpt/index/indexForProject.vue'),
|
||||
name: 'projectRpt',
|
||||
meta: {
|
||||
title: '项目-效能',
|
||||
icon: 'project',
|
||||
roles: ['user'],
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/xm/pro/product/view',
|
||||
component: XmProductLayout,
|
||||
name: 'XmProProductView',
|
||||
meta: {
|
||||
title: '产品管理',
|
||||
icon: 'product',
|
||||
hidden: true,
|
||||
},
|
||||
// leaf: true,//只有一个节点
|
||||
children: [
|
||||
{
|
||||
path: 'contract',
|
||||
component: () => import('@/views/xm/pro/xmContract/XmContractForProduct.vue'),
|
||||
name: 'productContract',
|
||||
meta: {
|
||||
title: '产品-合同',
|
||||
icon: 'product',
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'budget',
|
||||
component: () => import('@/views/xm/pro/fin/XmBudgetForProduct.vue'),
|
||||
name: 'productBudget',
|
||||
meta: {
|
||||
title: '产品-预算',
|
||||
icon: 'product',
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'cost',
|
||||
component: () => import('@/views/xm/pro/fin/XmCostForProduct.vue'),
|
||||
name: 'productCost',
|
||||
meta: {
|
||||
title: '产品-成本',
|
||||
icon: 'product',
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'workloadMonth',
|
||||
component: () => import('@/views/xm/pro/rpt/workload/WorkloadSetMonthList.vue'),
|
||||
name: 'productWorkloadMonth',
|
||||
meta: {
|
||||
title: '产品-工时月报',
|
||||
icon: 'product',
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'rpt',
|
||||
component: () => import('@/views/xm/pro/rpt/index/indexForProduct.vue'),
|
||||
name: 'productRpt',
|
||||
meta: {
|
||||
title: '产品-效能',
|
||||
icon: 'product',
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: '/xm/pro/iteration/view',
|
||||
component: XmIterationLayout,
|
||||
name: 'XmProIterationView',
|
||||
meta: {
|
||||
title: '迭代管理',
|
||||
icon: 'iteration',
|
||||
hidden: true,
|
||||
},
|
||||
// leaf: true,//只有一个节点
|
||||
children: [
|
||||
{
|
||||
path: 'workloadMonth',
|
||||
component: () => import('@/views/xm/pro/rpt/workload/WorkloadSetMonthList.vue'),
|
||||
name: 'iterationWorkloadMonth',
|
||||
meta: {
|
||||
title: '迭代-工时月报',
|
||||
icon: 'iteration',
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'rpt',
|
||||
component: () => import('@/views/xm/pro/rpt/index/indexForIteration.vue'),
|
||||
name: 'iterationRpt',
|
||||
meta: {
|
||||
title: '迭代-效能',
|
||||
icon: 'iteration',
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/xm/pro/test/view',
|
||||
component: XmTestLayout,
|
||||
name: 'XmProTestView',
|
||||
meta: {
|
||||
title: '测试管理',
|
||||
icon: 'bug',
|
||||
hidden: true,
|
||||
},
|
||||
// leaf: true,//只有一个节点
|
||||
children: [
|
||||
{
|
||||
path: 'rpt',
|
||||
component: () => import('@/views/xm/pro/rpt/index/indexForTest.vue'),
|
||||
name: 'testRpt',
|
||||
meta: { title: '统计分析', roles: ['user'], hidden: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
export default RoutesXmCore
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<template>
|
||||
|
||||
<!--编辑界面 XmEnvList xm_env_list-->
|
||||
<el-form :model="editForm" label-width="120px" :rules="editFormRules" ref="editForm" label-position="left">
|
||||
<el-form-item label="名称" prop="name">
|
||||
@@ -60,15 +59,14 @@
|
||||
</el-row>
|
||||
<el-form-item label="备注说明" prop="remark">
|
||||
<el-input type="textarea" rows="4" v-model="editForm.remark" placeholder="备注说明" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-col :span="24" :offset="8">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button v-loading="load.edit" type="primary" @click="editSubmit" :disabled="load.edit==true">提交</el-button>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div class="footer">
|
||||
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button v-loading="load.edit" type="primary" @click="editSubmit" :disabled="load.edit==true">提交</el-button>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -13,10 +13,12 @@
|
||||
@addTopNode="(cb) => onAddTopClick(cb)"
|
||||
@editNode="(d, cb, subcb) => onEditClick(d, cb, subcb)"
|
||||
@addSubNode="(p, cb) => onAddSubClick(p, cb)"
|
||||
@changePid="(cks,cb) => onChangePidClick(cks,cb)"
|
||||
@confirm = "(d)=>{$emit('confirm',d);$emit('select',d)}"
|
||||
@check-change="(d,c,i)=>$emit('check-change',d,c,i)"
|
||||
@node-click="(d,n,c)=>$emit('node-click',d,n,c)"
|
||||
rootId="0"
|
||||
:draggable="true"
|
||||
>
|
||||
<template #topToolbar>
|
||||
<xm-product-select width="300px"
|
||||
@@ -69,7 +71,8 @@
|
||||
import {
|
||||
delXmFunc,
|
||||
batchDelXmFunc,
|
||||
listXmFunc
|
||||
listXmFunc,
|
||||
batchChangeParent,
|
||||
} from '@/api/xm/core/xmFunc'
|
||||
|
||||
import XmProductSelect from '@/views/xm/core/components/XmProductSelect.vue' //新增界面
|
||||
@@ -99,7 +102,7 @@
|
||||
var hidden ={
|
||||
batchDel: isSelect,
|
||||
del:isSelect,
|
||||
changePid: true,
|
||||
changePid: false,
|
||||
addTop: isSelect,
|
||||
addSub: isSelect,
|
||||
edit: isSelect,
|
||||
@@ -205,7 +208,19 @@
|
||||
callback: callback
|
||||
})
|
||||
},
|
||||
|
||||
onChangePidClick: function(idLinks,callback){
|
||||
batchChangeParent(idLinks).then(res=>{
|
||||
let {tips}=res
|
||||
if(tips.isOk){
|
||||
if(callback){
|
||||
callback(true)
|
||||
}
|
||||
this.$message.success(tips.msg)
|
||||
}else{
|
||||
this.$message.error(tips.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
onProductSelected: function (product) {
|
||||
this.product = product
|
||||
this.$refs['nodeTree'].refresh()
|
||||
|
||||
@@ -6,39 +6,35 @@
|
||||
<el-input v-model="editForm.groupName" placeholder="团队名称">
|
||||
<template v-if="currOpType=='edit'" #append>{{editForm.lvl}}级</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="组长" prop="leaderUsername">
|
||||
<MdpSelectUser width="100%" v-model="editForm.leaderUserid" :init-name="editForm.leaderUsername"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="负责人" prop="leaderUsername">
|
||||
<el-form-item label="组长" prop="leaderUsername">
|
||||
<el-input v-model="editForm.leaderUsername" placeholder="组长人姓名" @click="showUserSelect('leader')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="副组长" prop="assUsername">
|
||||
<el-input v-model="editForm.assUsername" placeholder="副组长姓名" @click="showUserSelect('ass')"/>
|
||||
<font color="blue">如果没有副组长可以设置为项目助理、小组助理等,具有组长同等权限</font>
|
||||
</el-form-item>
|
||||
</el-form-item>
|
||||
<el-form-item label="企业协作" prop="isCrow">
|
||||
<el-form-item label="" prop="isCrow">
|
||||
<el-form-item label="副组长" prop="assUsername">
|
||||
<MdpSelectUser width="100%" v-model="editForm.assUserid" :init-name="editForm.assUsername"/>
|
||||
<el-text type="primary">如果没有副组长可以设置为项目助理、小组助理等,具有组长同等权限</el-text>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="归属产品" prop="productId">
|
||||
<XmProductSelect width="100%" v-model="editForm.productId" :link-project-id="editForm.projectId"/>
|
||||
<el-text type="primary">关联上产品,可以将小组归属到产品上</el-text>
|
||||
</el-form-item>
|
||||
<el-form-item label="企业协作" prop="isCrow">
|
||||
<el-checkbox v-model="editForm.isCrow" true-label="1" false-label="0">是否属于协作公司</el-checkbox>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="协作公司" prop="crowBranchId" v-if="editForm.isCrow=='1'">
|
||||
<mdp-select-branch width="100%" v-model="editForm.crowBranchId" :init-name="editForm.crowBranchName" @change2="branchRowClick" />
|
||||
|
||||
<el-text type="primary">如果该团队属于某协作公司,请选择协作公司。</el-text>
|
||||
</el-form-item>
|
||||
<el-form-item label="协作公司" prop="crowBranchName" v-if="editForm.isCrow">
|
||||
<el-input v-model="editForm.crowBranchName" placeholder="协作公司名称" @click="branchVisible=true"/>
|
||||
<font color="blue">如果该团队属于某协作公司,请选择协作公司。</font>
|
||||
</el-form-item>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row class="page-bottom bottom-fixed">
|
||||
<div class="footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button v-loading="load.edit" type="primary" @click="saveSubmit" :disabled="load.edit==true">提交</el-button>
|
||||
</el-row>
|
||||
|
||||
<mdp-dialog append-to-body title="选择员工" v-model="userSelectVisible" width="60%">
|
||||
<users-select isSingleUser=true @confirm="onUserSelected" ref="usersSelect" />
|
||||
</mdp-dialog>
|
||||
|
||||
<mdp-dialog title="机构选择" v-model="branchVisible" size="50%" top="20" :close-on-click-modal="false" append-to-body>
|
||||
<branch-select :visible="branchVisible" @cancel="branchVisible=false" @row-click="branchRowClick" />
|
||||
</mdp-dialog>
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
@@ -48,12 +44,12 @@
|
||||
|
||||
import { addXmGroup,editXmGroup } from '@/api/xm/core/xmGroup';
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import XmProductSelect from '@/views/xm/core/components/XmProductSelect.vue' //新增界面
|
||||
export default {
|
||||
name:'xmGroupEdit',
|
||||
components: {
|
||||
|
||||
XmProductSelect
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore,[ 'userInfo' ]),
|
||||
@@ -168,8 +164,7 @@ import { useUserStore } from '@/store/modules/user'
|
||||
}
|
||||
|
||||
},
|
||||
branchRowClick: function(row, event, column){
|
||||
this.branchVisible=false
|
||||
branchRowClick: function(row){
|
||||
this.editForm.crowBranchId=row.id
|
||||
this.editForm.crowBranchName=row.branchName
|
||||
},
|
||||
|
||||
@@ -2,29 +2,27 @@
|
||||
<ContentWrap>
|
||||
|
||||
<el-space>
|
||||
<xm-project-select v-if="!selProject&&!xmProduct" :link-iteration-id="xmIteration?xmIteration.id:null" :link-product-id="xmProduct?xmProduct.id:null" @select="onProjectRowClick" @clear="onProjectClearSelect" />
|
||||
<xm-project-select v-if="!selProject" :link-iteration-id="xmIteration?xmIteration.id:null" :link-product-id="xmProduct?xmProduct.id:null" @select="onProjectRowClick" @clear="onProjectClearSelect" />
|
||||
|
||||
<el-input v-model="filters.groupName" style="width:15%;" clearable placeholder="名称过滤"/>
|
||||
<el-input v-model="filters.groupName" clearable placeholder="名称过滤"/>
|
||||
<el-button type="primary" @click="searchXmGroups" icon="search">刷新</el-button>
|
||||
<el-button type="plain" @click="showGroupState" icon="s-data">小组进度</el-button>
|
||||
<el-button class="hidden-lg-and-down" type="plain" @click="xmRecordVisible=true" icon="document">变化日志</el-button>
|
||||
<el-button class="hidden-lg-and-down" type="plain" @click="doSearchImGroupsByProjectId" icon="document">绑定即聊情况</el-button>
|
||||
<el-button type="plain" @click="showAllGroupDlg" icon="histogram">小组数据对比</el-button>
|
||||
<el-button class="hidden-lg-and-down" type="plain" @click="showRecord()" icon="document">变化日志</el-button>
|
||||
<!-- <el-button class="hidden-lg-and-down" type="plain" @click="doSearchImGroupsByProjectId" icon="document">绑定即聊情况</el-button> -->
|
||||
<el-button class="hidden-md-and-down" @click="groupRoleDescVisible=true" icon="document">角色说明</el-button>
|
||||
<font style="font-size:12px;" class="hidden-md-and-down" color="blue">点击架构图操作</font>
|
||||
<el-text type="info">架构图-右键-操作</el-text>
|
||||
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
width="500"
|
||||
trigger="click">
|
||||
<el-button type="plain" @click="xmRecordVisible=true" icon="document">变化日志</el-button>
|
||||
<el-button type="plain" @click="doSearchImGroupsByProjectId" icon="document">绑定即聊情况</el-button>
|
||||
<el-button @click="groupRoleDescVisible=true" icon="document">角色说明</el-button>
|
||||
<font style="font-size:12px;" color="blue">注意:点击架构图进行操作</font>
|
||||
<el-button @click="groupRoleDescVisible=true" icon="document">角色说明</el-button>
|
||||
<el-text type="info">注意:点击架构图-右键进行新增等操作</el-text>
|
||||
<template #reference><el-link type="warning" v-if="!selProject" icon="search">更多</el-link></template>
|
||||
</el-popover>
|
||||
</el-space>
|
||||
</ContentWrap>
|
||||
<Vue3TreeOrg v-adaptive :data="okrTreeData" v-loading="load.list" ref="tree" :props="{'id':'id','pid':'pgroupId',label:'label'}"
|
||||
<Vue3TreeOrg @contextmenu.prevent v-adaptive :data="okrTreeData" v-loading="load.list" ref="tree" :props="{'id':'id','pid':'pgroupId',label:'label'}"
|
||||
:node-draggable="true"
|
||||
:horizontal="false"
|
||||
:collapsable="true"
|
||||
@@ -120,7 +118,7 @@
|
||||
</el-collapse>
|
||||
|
||||
</el-row>
|
||||
<el-row class="padding">
|
||||
<el-row class="footer">
|
||||
<el-button type="primary" @click="groupRoleDescVisible=false">关闭</el-button>
|
||||
</el-row>
|
||||
</mdp-dialog>
|
||||
@@ -128,22 +126,15 @@
|
||||
<mdp-select-user @change2="onUserSelected" multiple/>
|
||||
</mdp-dialog>
|
||||
|
||||
<mdp-dialog v-if="selProject" :title="selProject==null?'操作日志':selProject.name+'团队操作日志'" center v-model="xmRecordVisible" width="80%" :close-on-click-modal="false" append-to-body>
|
||||
<xm-record :visible="xmRecordVisible" :project-id="selProject.id" objType="7" :simple="1" />
|
||||
</mdp-dialog>
|
||||
<mdp-dialog v-else-if="xmProduct&&!selProject" :title="xmProduct==null?'操作日志':xmProduct.productName+'团队操作日志'" center v-model="xmRecordVisible" width="80%" :close-on-click-modal="false" append-to-body>
|
||||
<xm-record :visible="xmRecordVisible" :product-id="xmProduct.id" objType="7" :simple="1" />
|
||||
</mdp-dialog>
|
||||
|
||||
<mdp-dialog v-if="currNodeType=='group'&&editForm.groupName" :title="editForm.groupName+'小组进度数据查看'" center v-model="xmGroupStateVisible" fullscreen :close-on-click-modal="false" append-to-body>
|
||||
<xm-group-state-mng :xm-group="editForm" :selProject="project" :visible="xmGroupStateVisible" />
|
||||
</mdp-dialog>
|
||||
<mdp-dialog v-else-if="selProject" :title="selProject.name+'小组进度数据查看'" center v-model="xmGroupStateVisible" fullscreen :close-on-click-modal="false" append-to-body>
|
||||
<xm-group-state-mng :sel-project="project" :visible="xmGroupStateVisible" />
|
||||
</mdp-dialog>
|
||||
<mdp-dialog v-else-if="!selProject && xmProduct" :title="xmProduct.productName+'小组进度数据查看'" center v-model="xmGroupStateVisible" fullscreen :close-on-click-modal="false" append-to-body>
|
||||
<xm-group-state-mng :xm-product="xmProduct" :visible="xmGroupStateVisible" />
|
||||
<mdp-dialog v-if="project" :title="project==null?'操作日志':project.name+'团队操作日志'" center v-model="xmRecordVisible" width="80%" :close-on-click-modal="false" append-to-body>
|
||||
<xm-record :visible="xmRecordVisible" :project-id="project.id" objType="7" :simple="1" />
|
||||
</mdp-dialog>
|
||||
<mdp-dialog ref="allGroupDlg" center fullscreen :close-on-click-modal="false" append-to-body>
|
||||
<xm-group-state-mng :selProject="project" />
|
||||
</mdp-dialog>
|
||||
<mdp-dialog ref="oneGroupDlg" center fullscreen :close-on-click-modal="false" append-to-body>
|
||||
<xm-group-state-mng :xm-group="editForm" :sel-project="project" />
|
||||
</mdp-dialog>
|
||||
<mdp-dialog v-if="currNodeType=='group'&&editForm.groupName" center :title="(editForm==null?editForm.groupName:'')+'小组成员管理'" v-model="groupUserVisible" width="80%" :close-on-click-modal="false" append-to-body>
|
||||
<xm-group-user-mng :xm-group="editForm" :visible="groupUserVisible" />
|
||||
</mdp-dialog>
|
||||
@@ -344,7 +335,7 @@ XmTaskExecuserSelect,
|
||||
{ name:'删除小组', command: 'del' },
|
||||
{ name:'拉部门人员进组', command: 'addDeptUsers' },
|
||||
{ name:'拉竞标人员进组', command: 'addHxUsers' },
|
||||
{ name:'查看小组进度', command: 'showGroupState' },
|
||||
{ name:'查看小组进度', command: 'showOneGroupDlg' },
|
||||
]
|
||||
}else if (currNodeType=='groupUser') {
|
||||
return [
|
||||
@@ -376,9 +367,9 @@ XmTaskExecuserSelect,
|
||||
this.handleDel(formData)
|
||||
}else if(command=='delGroupUser'){
|
||||
this.handleDelGroupUser(formData)
|
||||
}else if(command=='showGroupState'){
|
||||
}else if(command=='showOneGroupDlg'){
|
||||
this.editForm=formData
|
||||
this.showGroupState()
|
||||
this.showOneGroupDlg()
|
||||
}
|
||||
},
|
||||
restore(){
|
||||
@@ -386,6 +377,13 @@ XmTaskExecuserSelect,
|
||||
},
|
||||
onNodeClick(){
|
||||
|
||||
},
|
||||
showRecord(){
|
||||
if(!this.project||!this.project.id){
|
||||
this.$message.warning("请先选中项目")
|
||||
return;
|
||||
}
|
||||
this.xmRecordVisible=true
|
||||
},
|
||||
handleSizeChange(pageSize) {
|
||||
this.pageInfo.pageSize=pageSize;
|
||||
@@ -413,48 +411,33 @@ XmTaskExecuserSelect,
|
||||
}
|
||||
this.searchTableDatass();
|
||||
},
|
||||
searchXmGroups(){
|
||||
debugger
|
||||
this.pageInfo.count=true;
|
||||
this.searchTableDatass();
|
||||
},
|
||||
loadNexGroup(){
|
||||
|
||||
var params={}
|
||||
if(this.currNodeType=='branch'||this.currNodeType=='iteration'){
|
||||
params.branchId=this.editForm.branchId
|
||||
params.lvl=1
|
||||
}else if(this.currNodeType=='project'){
|
||||
params.projectId=this.editForm.id
|
||||
params.lvl=1
|
||||
}else if(this.currNodeType=='product'){
|
||||
params.productId=this.editForm.id
|
||||
params.lvl=1
|
||||
}else if(this.currNodeType=='group'){
|
||||
params.pgroupId=this.editForm.id
|
||||
}else if(this.currNodeType=='groupUser'){
|
||||
searchXmGroups(){
|
||||
if(!this.project||!this.project.id){
|
||||
this.$message.success("请先选中项目")
|
||||
return;
|
||||
}
|
||||
listXmGroup(params).then((res) => {
|
||||
var tips=res.tips;
|
||||
if(tips.isOk){
|
||||
this.pageInfo.total = res.total;
|
||||
this.pageInfo.count=false;
|
||||
var childrens = res.data;
|
||||
childrens=childrens.filter(i=>!this.xmGroups.some(k=>k.id==i.id))
|
||||
this.xmGroups.push(...childrens)
|
||||
this.$notify({position:'bottom-left',showClose:true, message: tips.msg+",返回"+res.data.length+"条数据。", type: tips.isOk?'success':'error' });
|
||||
}else{
|
||||
this.$notify({position:'bottom-left',showClose:true, message: tips.msg, type: tips.isOk?'success':'error' });
|
||||
}
|
||||
|
||||
|
||||
this.load.list = false;
|
||||
}).catch( err => this.load.list = false );
|
||||
this.pageInfo.count=true;
|
||||
this.searchTableDatass();
|
||||
},
|
||||
showAllGroupDlg(){
|
||||
if(!this.project ||!this.project.id){
|
||||
this.$message.success("请先选中项目")
|
||||
return;
|
||||
}else{
|
||||
this.$refs.allGroupDlg.open({title:this.project.projectName+"项目全体小组数据对比分析"})
|
||||
}
|
||||
},
|
||||
showOneGroupDlg(){
|
||||
if(!this.editForm ||!this.editForm.id){
|
||||
this.$message.success("请先选中小组")
|
||||
return;
|
||||
}else{
|
||||
this.$refs.oneGroupDlg.open({title:this.editForm.groupName+"小组数据分析"})
|
||||
}
|
||||
},
|
||||
//获取列表 XmGroup xm_group
|
||||
searchTableDatass() {
|
||||
debugger
|
||||
|
||||
let params = {
|
||||
pageSize: this.pageInfo.pageSize,
|
||||
pageNum: this.pageInfo.pageNum,
|
||||
@@ -468,16 +451,12 @@ XmTaskExecuserSelect,
|
||||
}
|
||||
params.orderBy= orderBys.join(",")
|
||||
}
|
||||
if( (!this.project || !this.project.id) && (!this.xmProduct || !this.xmProduct.id)){
|
||||
if( (!this.project || !this.project.id)){
|
||||
return;
|
||||
}
|
||||
if(this.project && this.project.id){
|
||||
params.projectId=this.project.id
|
||||
}
|
||||
|
||||
if(this.xmProduct && this.xmProduct.id){
|
||||
params.productId=this.xmProduct.id
|
||||
}
|
||||
if(this.filters.groupName){
|
||||
params.groupName=this.filters.groupName
|
||||
}
|
||||
@@ -525,31 +504,15 @@ XmTaskExecuserSelect,
|
||||
this.addForm.projectId=this.project.id
|
||||
this.addForm.groupName=this.project.name+"-项目管理组"
|
||||
this.addFormVisible = true;
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
if(this.xmProduct && this.xmProduct.id){
|
||||
this.addForm.productId=this.xmProduct.id
|
||||
}
|
||||
//this.addForm=Object.assign({}, this.editForm);
|
||||
},
|
||||
//显示新增界面 XmGroup xm_group
|
||||
showProductGroupAdd: function () {
|
||||
if(!this.xmProduct || !this.xmProduct.id){
|
||||
this.$notify({position:'bottom-left',showClose:true, message: "请先选择产品", type: 'warning' });
|
||||
return;
|
||||
}
|
||||
this.addForm={...this.addFormInit}
|
||||
if(this.currNodeType=='product'){
|
||||
this.addForm.pgroupId=null
|
||||
this.addForm.pgroupName=null
|
||||
this.addForm.productId=this.xmProduct.id
|
||||
this.addForm.pgClass="1"
|
||||
this.addForm.groupName=this.xmProduct.productName+"-产品管理组"
|
||||
this.addFormVisible = true;
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
|
||||
//this.addForm=Object.assign({}, this.editForm);
|
||||
showProductGroupAdd: function () {
|
||||
this.showProjectGroupAdd()
|
||||
},
|
||||
//显示新增界面 XmGroup xm_group
|
||||
showAddSub: function (row) {
|
||||
@@ -618,11 +581,7 @@ XmTaskExecuserSelect,
|
||||
this.$notify({position:'bottom-left',showClose:true, message: tips.msg, type: tips.isOk?'success':'error'});
|
||||
}).catch( err => this.load.del=false );
|
||||
});
|
||||
},
|
||||
|
||||
showGroupState(){
|
||||
this.xmGroupStateVisible=true;
|
||||
},
|
||||
},
|
||||
doSearchImGroupsByProjectId(){
|
||||
|
||||
var params={bizPid:this.selProject.id}
|
||||
@@ -792,7 +751,7 @@ XmTaskExecuserSelect,
|
||||
this.selectProjectVisible=false;
|
||||
},
|
||||
onProjectRowClick(project){
|
||||
debugger
|
||||
|
||||
this.project=project;
|
||||
this.searchXmGroups();
|
||||
},
|
||||
|
||||
@@ -50,9 +50,9 @@
|
||||
<mdp-dialog
|
||||
append-to-body
|
||||
title="小组概览"
|
||||
v-model="overviewVisible" width="80%"
|
||||
v-model="overviewVisible" width="80%" fullscreen
|
||||
>
|
||||
<XmGroupStateOverview :xm-group-state="editForm" />
|
||||
<XmGroupStateOverview v-if="overviewVisible" :xm-group-state="editForm"/>
|
||||
</mdp-dialog>
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ export default {
|
||||
'userInfo','roles'
|
||||
])
|
||||
},
|
||||
props:['selProject','visible','xmProduct','xmGroup'],
|
||||
props:['selProject','visible','xmGroup'],
|
||||
watch:{
|
||||
visible(visible){
|
||||
if(visible==true){
|
||||
@@ -106,10 +106,6 @@ export default {
|
||||
params.projectId=this.selProject.id
|
||||
}
|
||||
|
||||
if(this.xmProduct){
|
||||
params.productId=this.xmProduct.id
|
||||
}
|
||||
|
||||
if(this.xmGroup){
|
||||
params.groupId=this.xmGroup.id
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<el-form-item :label="editForm.pgClass=='1'?'产品编号':'项目编号'" prop="pgClass">
|
||||
{{editForm.projectId?editForm.projectId:''}}{{editForm.productId?editForm.productId:''}}
|
||||
</el-form-item>
|
||||
<el-form-item label="小组名称" prop="groupName">
|
||||
<el-input v-model="editForm.groupName" placeholder="小组名称"/>
|
||||
<el-form-item label="小组名称" prop="groupName">
|
||||
<el-text type="primary">{{editForm.groupName}}</el-text>
|
||||
</el-form-item>
|
||||
<el-form-item label="组员姓名" prop="username">
|
||||
<el-input v-model="editForm.username" placeholder="组员姓名"/>
|
||||
@@ -19,8 +19,8 @@
|
||||
<el-form-item label="排序号" prop="seqNo">
|
||||
<el-input-number v-model="editForm.seqNo" :min="0" :max="200" />
|
||||
</el-form-item>
|
||||
<el-form-item label="原归属机构名称" prop="obranchName">
|
||||
<el-input v-model="editForm.obranchName" placeholder="原归属机构名称"/>
|
||||
<el-form-item label="原归属机构名称" prop="obranchName">
|
||||
<MdpSelectBranch width="100%" v-model="editForm.obranchId" :init-name="editForm.obranchName"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="加入时间" prop="joinTime">
|
||||
<el-date-picker type="date" placeholder="选择日期" v-model="editForm.joinTime" value-format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD" />
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
</el-space>
|
||||
</template>
|
||||
<el-space>
|
||||
<XmProjectSelect v-model="filters['res.projectId']" placeholder="项目"/>
|
||||
<el-input v-model="filters.groupName" style="width:15%;" clearable placeholder="小组名称查询"/>
|
||||
<el-input v-model="filters.leaderUsername" style="width:15%;" clearable placeholder="组长名称查询"/>
|
||||
<el-input v-model="filters.assUsername" style="width:15%;" clearable placeholder="副组长名称查询"/>
|
||||
@@ -100,6 +101,7 @@
|
||||
import XmGroupUserEdit from './XmGroupUserEdit.vue';//新增修改界面
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import XmProjectSelect from '@/views/xm/core/components/XmProjectSelect.vue';
|
||||
|
||||
import { MdpTableMixin } from '@/components/mdp-ui/mixin/MdpTableMixin.js'
|
||||
|
||||
@@ -107,7 +109,7 @@ import { MdpTableMixin } from '@/components/mdp-ui/mixin/MdpTableMixin.js'
|
||||
mixins:[MdpTableMixin],
|
||||
name:'xmGroupUserMng',
|
||||
components: {
|
||||
XmGroupUserEdit,
|
||||
XmGroupUserEdit,XmProjectSelect
|
||||
},
|
||||
props:['visible','xmGroup'],
|
||||
computed: {
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<el-menu-item :index="'/xm/iteration/view/group?iterationId='+xmIteration.id">
|
||||
<template #title><i class="user-solid"></i>团队</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item :index="'/xm/iteration/view/rpt?iterationId='+xmIteration.id">
|
||||
<el-menu-item :index="'/xm/pro/iteration/view/rpt?iterationId='+xmIteration.id">
|
||||
<template #title><i class="s-data"></i>效能</template>
|
||||
</el-menu-item>
|
||||
<el-sub-menu index="更多">
|
||||
@@ -52,7 +52,7 @@
|
||||
<el-menu-item :index="'/xm/iteration/view/workloadDay?iterationId='+xmIteration.id">
|
||||
<template #title><i class="video-camera"></i>每日工时</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item :index="'/xm/iteration/view/workloadMonth?iterationId='+xmIteration.id">
|
||||
<el-menu-item :index="'/xm/pro/iteration/view/workloadMonth?iterationId='+xmIteration.id">
|
||||
<template #title
|
||||
><i class="video-camera"></i>每月工时</template
|
||||
>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
@check-change="(d,c,i)=>$emit('check-change',d,c,i)"
|
||||
@node-click="(d,n,c)=>$emit('node-click',d,n,c)"
|
||||
rootId="0"
|
||||
:draggable="true"
|
||||
>
|
||||
<template #topToolbar>
|
||||
<xm-product-select width="300px"
|
||||
@@ -78,14 +79,6 @@
|
||||
/>
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
<mdp-dialog append-to-body width="60%" top="20px" ref="parentDialog">
|
||||
<template #default="{data,dialog}">
|
||||
<XmEpicFeaturesSelect showConfirm subOpType="select"
|
||||
:xm-product="xmProduct ? xmProduct : product"
|
||||
@confirm="(menu)=>{onParentMenuSelected(menu,data.checkKeys,data.callback);dialog.close()}"
|
||||
/>
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -108,10 +101,7 @@ import { useUserStore } from '@/store/modules/user'
|
||||
// 在 Vue 3 中,可以使用 defineAsyncComponent 方法来创建异步组件
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
|
||||
// 创建一个异步组件,它会从一个外部API动态导入组件
|
||||
const XmEpicFeaturesSelect = defineAsyncComponent(() =>
|
||||
import('./XmEpicFeatures.vue') // 假设LazyComponent.vue是你想要懒加载的组件
|
||||
);
|
||||
|
||||
// 创建一个异步组件,它会从一个外部API动态导入组件
|
||||
const XmMenuAdd = defineAsyncComponent(() =>
|
||||
import('./XmMenuAdd.vue') // 假设LazyComponent.vue是你想要懒加载的组件
|
||||
@@ -260,8 +250,22 @@ export default {
|
||||
callback: callback
|
||||
})
|
||||
},
|
||||
onChangePidClick: function(checkKeys,callback){
|
||||
this.$refs['parentDialog'].open({callback:callback,checkKeys:checkKeys})
|
||||
onChangePidClick: function(idLinks,callback){
|
||||
|
||||
|
||||
batchChangeParentMenu(idLinks).then(res=>{
|
||||
let {tips}=res
|
||||
if(tips.isOk){
|
||||
if(callback){
|
||||
callback(true)
|
||||
}
|
||||
this.$message.success(tips.msg)
|
||||
}else{
|
||||
this.$message.error(tips.msg)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
},
|
||||
|
||||
onProductSelected: function (product) {
|
||||
@@ -386,48 +390,12 @@ export default {
|
||||
})
|
||||
})
|
||||
.catch((err) => (this.load.edit = false))
|
||||
},
|
||||
onParentMenuSelected(menu,checkKeys,callback) {
|
||||
if (!menu || !menu.menuId) {
|
||||
this.$notify({
|
||||
position: 'bottom-left',
|
||||
showClose: true,
|
||||
message: '请先选择一个上级需求',
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (menu.dclass != '1') {
|
||||
this.$notify({
|
||||
position: 'bottom-left',
|
||||
showClose: true,
|
||||
message: menu.menuName + '是特性,不能作为上级,请选择史诗作为上级',
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
var params = {
|
||||
menuIds: checkKeys,
|
||||
pmenuId: menu.menuId
|
||||
}
|
||||
batchChangeParentMenu(params).then((res) => {
|
||||
var tips = res.tips
|
||||
if (tips.isOk) {
|
||||
this.$refs['nodeTree'].refresh()
|
||||
}
|
||||
this.$notify({
|
||||
position: 'bottom-left',
|
||||
showClose: true,
|
||||
message: tips.msg,
|
||||
type: tips.isOk ? 'success' : 'error'
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
}, //end methods
|
||||
components: {
|
||||
'xm-menu-add': XmMenuAdd,
|
||||
'xm-menu-edit': XmMenuEdit,
|
||||
XmProductSelect,XmEpicFeaturesSelect
|
||||
XmProductSelect
|
||||
//在下面添加其它组件
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -117,11 +117,11 @@
|
||||
</mdp-field>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<mdp-select-user show-style="x" label="负责人" v-model="editForm.mmUserid"
|
||||
<mdp-select-user show-style="x" label="负责人" v-model="editForm.mmUserid" :init-name="editForm.mmUsername"
|
||||
@change2="editSomeFields(editForm, 'mmUserid', $event)" />
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<mdp-select-user show-style="x" label="提出人" v-model="editForm.proposerId"
|
||||
<mdp-select-user show-style="x" label="提出人" v-model="editForm.proposerId" :init-name="editForm.proposerName"
|
||||
@change2="editSomeFields(editForm, 'proposerId', $event)" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -216,24 +216,23 @@
|
||||
placeholder="什么人?做什么事?,为什么?如: 作为招聘专员,我需要统计员工半年在职/离职人数,以便我能够制定招聘计划" />
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'任务( ' + (subWorkitemCpd ? subWorkitemCpd : 0) + ' )'" name="64" v-if="editForm.dclass=='3'">
|
||||
<el-tab-pane :label="'任务( ' + (editForm.taskCnt||0) + ' )'" name="64" v-if="editForm.dclass=='3'">
|
||||
|
||||
<XmTaskMng v-if="activateTabPaneName == '64'" :xm-product="{id:editForm.productId,productName:editForm.productName}"
|
||||
:selProject="selProject" @loadDatas="setSubWorkItemNum"
|
||||
:selProject="selProject"
|
||||
@add-submit="onAddSubMenu" :menuId="editForm.menuId"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'子项( ' + (subWorkitemCpd ? subWorkitemCpd : 0) + ' )'" name="64" v-if="editForm.dclass<'3'">
|
||||
<el-tab-pane :label="'子项( ' + (editForm.childrenCnt||0) + ' )'" name="64" v-if="editForm.dclass<'3'">
|
||||
<XmMenuMng v-if="activateTabPaneName == '64'" :parent-menu="editForm"
|
||||
:xm-product="{id:editForm.productId,productName:editForm.productName}"
|
||||
@loadDatas="setSubWorkItemNum"
|
||||
:xm-product="{id:editForm.productId,productName:editForm.productName}"
|
||||
@add-submit="onAddSubMenu" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'缺陷(' + (editForm.bugCnt ? editForm.bugCnt : 0) + ')'" name="63">
|
||||
<el-tab-pane :label="'缺陷(' + (editForm.bugCnt||0) + ')'" name="63">
|
||||
<xm-question-mng v-if="activateTabPaneName == '63'"
|
||||
:xm-product="editForm.productId ? { id: editForm.productId, productName: editForm.productName } : null"
|
||||
:xm-menu="editForm" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'测试用例(' + (editForm.testCases ? editForm.testCases : 0) + ')'" name="62">
|
||||
<el-tab-pane :label="'测试用例(' + (editForm.testCases|| 0) + ')'" name="62">
|
||||
<xm-test-case-mng v-if="activateTabPaneName == '62'"
|
||||
:xm-product="{ id: editForm.productId, productName: editForm.productName }" :xm-menu="editForm" />
|
||||
</el-tab-pane>
|
||||
@@ -352,22 +351,7 @@ import { MdpFormMixin } from '@/components/mdp-ui/mixin/MdpFormMixin';
|
||||
}
|
||||
return params;
|
||||
},
|
||||
subWorkitemCpd() {
|
||||
if (this.subWorkItemNum > 0) {
|
||||
return this.subWorkItemNum
|
||||
} else {
|
||||
if (this.editForm.dclass == '3') {
|
||||
var taskCnt = 0;
|
||||
if (this.editForm.taskCnt) {
|
||||
taskCnt = parseInt(this.editForm.taskCnt)
|
||||
}
|
||||
return taskCnt;
|
||||
} else {
|
||||
return this.editForm.childrenCnt
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
props: ['xmMenu', 'visible', 'parentMenu', 'product', 'dclass', 'selProject', 'reload'],
|
||||
watch: {
|
||||
@@ -375,8 +359,7 @@ import { MdpFormMixin } from '@/components/mdp-ui/mixin/MdpFormMixin';
|
||||
//this.editForm = {...xmMenu};
|
||||
},
|
||||
'visible': function (visible) {
|
||||
if (visible == true) {
|
||||
this.subWorkItemNum = 0;
|
||||
if (visible == true) {
|
||||
if (this.reload == true) {
|
||||
this.searchXmMenus();
|
||||
} else {
|
||||
@@ -442,8 +425,7 @@ import { MdpFormMixin } from '@/components/mdp-ui/mixin/MdpFormMixin';
|
||||
menuStatus: [
|
||||
]
|
||||
},
|
||||
tagSelectVisible: false,
|
||||
subWorkItemNum: -1,
|
||||
tagSelectVisible: false,
|
||||
activateTabPaneName: '4',
|
||||
pmenuFormVisible: false,
|
||||
parentMenuVisible: false,
|
||||
@@ -457,10 +439,7 @@ import { MdpFormMixin } from '@/components/mdp-ui/mixin/MdpFormMixin';
|
||||
/**end 在上面加自定义属性**/
|
||||
}//end return
|
||||
},//end data
|
||||
methods: {
|
||||
setSubWorkItemNum(val) {
|
||||
this.subWorkItemNum = val.total;
|
||||
},
|
||||
methods: {
|
||||
// 取消按钮点击 父组件监听@cancel="editFormVisible=false" 监听
|
||||
handleCancel: function () {
|
||||
this.$emit('cancel');
|
||||
|
||||
@@ -901,10 +901,7 @@ export default {
|
||||
})
|
||||
return
|
||||
}
|
||||
var params = {
|
||||
menuIds: this.sels.map((i) => i.menuId),
|
||||
pmenuId: menu.menuId
|
||||
}
|
||||
var params = this.sels.map((i) => { return {menuId:i.menuId,pmenuId:menu.menuId}})
|
||||
batchChangeParentMenu(params).then((res) => {
|
||||
var tips = res.tips
|
||||
if (tips.isOk) {
|
||||
|
||||
@@ -56,17 +56,17 @@
|
||||
</el-menu-item>
|
||||
<el-sub-menu index="caiwu" class="hidden-sm-and-down">
|
||||
<template #title><i class="coin"></i>财务</template>
|
||||
<el-menu-item :index="'/xm/product/view/contract?productId='+xmProduct.id">
|
||||
<el-menu-item :index="'/xm/pro/product/view/contract?productId='+xmProduct.id">
|
||||
<template #title><i class="s-data"></i>合同管理</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item :index="'/xm/product/view/budget?productId='+xmProduct.id">
|
||||
<el-menu-item :index="'/xm/pro/product/view/budget?productId='+xmProduct.id">
|
||||
<template #title><i class="coin"></i>预算</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item :index="'/xm/product/view/cost?productId='+xmProduct.id">
|
||||
<el-menu-item :index="'/xm/pro/product/view/cost?productId='+xmProduct.id">
|
||||
<template #title><i class="coin"></i>费用</template>
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
<el-menu-item :index="'/xm/product/view/rpt?productId='+xmProduct.id">
|
||||
<el-menu-item :index="'/xm/pro/product/view/rpt?productId='+xmProduct.id">
|
||||
<template #title><i class="s-data"></i>效能</template>
|
||||
</el-menu-item>
|
||||
<el-sub-menu index="zhishi" class="hidden-md-and-down">
|
||||
@@ -88,7 +88,7 @@
|
||||
><i class="video-camera"></i>每日工时</template
|
||||
>
|
||||
</el-menu-item>
|
||||
<el-menu-item :index="'/xm/product/view/workloadMonth?productId='+xmProduct.id">
|
||||
<el-menu-item :index="'/xm/pro/product/view/workloadMonth?productId='+xmProduct.id">
|
||||
<template #title
|
||||
><i class="video-camera"></i>每月工时</template
|
||||
>
|
||||
|
||||
@@ -58,17 +58,17 @@
|
||||
</el-menu-item>
|
||||
<el-sub-menu index="caiwu" class="hidden-sm-and-down">
|
||||
<template #title><i class="coin"></i>财务</template>
|
||||
<el-menu-item :index="'/xm/project/view/contract?projectId='+projectInfo.id">
|
||||
<el-menu-item :index="'/xm/pro/project/view/contract?projectId='+projectInfo.id">
|
||||
<template #title><i class="s-data"></i>合同管理</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item :index="'/xm/project/view/budget?projectId='+projectInfo.id">
|
||||
<el-menu-item :index="'/xm/pro/project/view/budget?projectId='+projectInfo.id">
|
||||
<template #title><i class="coin"></i>预算</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item :index="'/xm/project/view/cost?projectId='+projectInfo.id">
|
||||
<el-menu-item :index="'/xm/pro/project/view/cost?projectId='+projectInfo.id">
|
||||
<template #title><i class="coin"></i>费用</template>
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
<el-menu-item :index="'/xm/project/view/rpt?projectId='+projectInfo.id">
|
||||
<el-menu-item :index="'/xm/pro/project/view/rpt?projectId='+projectInfo.id">
|
||||
<template #title><i class="s-data"></i>效能</template>
|
||||
</el-menu-item>
|
||||
<el-sub-menu index="zhishi" class="hidden-md-and-down">
|
||||
@@ -90,7 +90,7 @@
|
||||
><i class="video-camera"></i>每日工时</template
|
||||
>
|
||||
</el-menu-item>
|
||||
<el-menu-item :index="'/xm/project/view/workloadMonth?projectId='+projectInfo.id">
|
||||
<el-menu-item :index="'/xm/pro/project/view/workloadMonth?projectId='+projectInfo.id">
|
||||
<template #title
|
||||
><i class="video-camera"></i>每月工时</template
|
||||
>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<el-form-item>
|
||||
<mdp-select-user show-style="x" size="medium" label="责任人" v-model="editForm.handlerUserid"
|
||||
<mdp-select-user show-style="x" size="medium" label="责任人" v-model="editForm.handlerUserid" :init-name="editForm.handlerUsername"
|
||||
@change="editSomeFields(editForm, 'handlerUserid', $event)">
|
||||
<template #extOpe>
|
||||
指派给 <el-button type="text" @click="sendToAsk"> 提出人</el-button> <el-button type="text"
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column prop="tagNames" label="标签" width="120" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<MdpSelectTag showStyle="tag" multiple v-model="scope.row.tagIds" @change2="editSomeFields(scope.row,'tagIds',$event)"/>
|
||||
<MdpSelectTag showStyle="tag" multiple v-model="scope.row.tagIds" :init-name="scope.row.tagNames" @change2="editSomeFields(scope.row,'tagIds',$event)"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="menuName" label="需求" width="120" show-overflow-tooltip />
|
||||
@@ -432,7 +432,7 @@ import { MdpTableMixin } from '@/components/mdp-ui/mixin/MdpTableMixin.js';
|
||||
return msg;
|
||||
},
|
||||
editSomeFieldsCheck(row,fieldName,$event,params){
|
||||
debugger
|
||||
|
||||
if(fieldName==='handlerUserid'){
|
||||
if($event){
|
||||
params[fieldName]=$event.userid;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
@check-change="(d,c,i)=>$emit('check-change',d,c,i)"
|
||||
@node-click="(d,n,c)=>$emit('node-click',d,n,c)"
|
||||
rootId="0"
|
||||
:draggable="true"
|
||||
>
|
||||
<template #topToolbar>
|
||||
<xm-project-select width="300px"
|
||||
@@ -63,7 +64,7 @@
|
||||
@cancel="dialog.close()"
|
||||
@submit="data.callback"
|
||||
@add-sub-task="data.addSubCallback"
|
||||
@edit-fields="data.callback"
|
||||
@fields-change="(res,isOk,params,row)=>data.callback(row)"
|
||||
/>
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
@@ -172,7 +173,7 @@ export default {
|
||||
project:null,
|
||||
props:{
|
||||
id: 'id', pid: 'parentTaskid', label: 'name' ,
|
||||
isLeaf:(n)=>{
|
||||
isLeaf:(n,node)=>{
|
||||
return n.subPlanCnt<=0||n.childrenCnt<=0
|
||||
}
|
||||
}
|
||||
@@ -219,7 +220,7 @@ export default {
|
||||
},
|
||||
//显示新增界面 XmTask xm_project_menu
|
||||
onAddTopClick: function (callback) {
|
||||
debugger
|
||||
|
||||
let ntype = '1'
|
||||
var parentTask = null
|
||||
var formData = {}
|
||||
@@ -277,8 +278,18 @@ export default {
|
||||
callback: callback
|
||||
})
|
||||
},
|
||||
onChangePidClick: function(checkKeys,callback){
|
||||
this.$refs['parentDialog'].open({callback:callback,checkKeys:checkKeys})
|
||||
onChangePidClick: function(idLinks,callback){
|
||||
batchChangeParentTask(idLinks).then(res=>{
|
||||
let {tips}=res
|
||||
if(tips.isOk){
|
||||
if(callback){
|
||||
callback(true)
|
||||
}
|
||||
this.$message.success(tips.msg)
|
||||
}else{
|
||||
this.$message.error(tips.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onProjectSelected: function (project) {
|
||||
|
||||
@@ -170,15 +170,15 @@
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item>
|
||||
<mdp-select-user show-style="x" label="负责人" v-model="editForm.createUserid" @change2="editSomeFields(editForm,'createUserid',$event)"/>
|
||||
<mdp-select-user show-style="x" label="负责人" v-model="editForm.createUserid" @change2="editSomeFields(editForm,'createUserid',$event)" :init-name="editForm.createUsername"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" v-if="editForm.ntype=='0'">
|
||||
<el-form-item>
|
||||
<mdp-select-user show-style="x" v-if="editForm.crowd=='1'" label="执行人" v-model="editForm.executorUserid">
|
||||
<mdp-select-user show-style="x" v-if="editForm.crowd=='1'" label="执行人" v-model="editForm.executorUserid" :init-name="editForm.executorUsername">
|
||||
<template #oper><el-button @click="activateTabPaneName='42'">去管理竞标人</el-button></template>
|
||||
</mdp-select-user>
|
||||
<mdp-select-user show-style="x" v-if="editForm.crowd!='1'" label="执行人" v-model="editForm.executorUserid" @change2="editSomeFields(editForm,'executorUserid',$event)"/>
|
||||
<mdp-select-user show-style="x" v-if="editForm.crowd!='1'" label="执行人" v-model="editForm.executorUserid" :init-name="editForm.executorUsername" @change2="editSomeFields(editForm,'executorUserid',$event)"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
@@ -323,11 +323,11 @@
|
||||
</el-form-item>
|
||||
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'子计划('+(subPlanNumCpd||0)+')'" name="45" v-if="editForm.ntype==='1'">
|
||||
<XmTaskMng v-if="activateTabPaneName=='45'" :parent-task="editForm" @loadDatas="setSubPlanNum" @add-submit="onAddSubTask" queryScope="plan"/>
|
||||
<el-tab-pane :label="'子计划('+(editForm.subPlanCnt||0)+')'" name="45" v-if="editForm.ntype==='1'">
|
||||
<XmTaskMng v-if="activateTabPaneName=='45'" :parent-task="editForm" @add-submit="onAddSubTask" queryScope="plan"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'子任务('+ (subWorkItemNumCpd||0) +')'" name="46" v-if="editForm.ntype==='1'">
|
||||
<XmTaskMng v-if="activateTabPaneName=='46'" :parent-task="editForm" @loadDatas="setSubWorkItemNum" @add-submit="onAddSubTask" queryScope="task"/>
|
||||
<el-tab-pane :label="'子任务('+ (editForm.subTaskCnt||0) +')'" name="46" v-if="editForm.ntype==='1'">
|
||||
<XmTaskMng v-if="activateTabPaneName=='46'" :parent-task="editForm" @add-submit="onAddSubTask" queryScope="task"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="缺陷" name="41" v-if="editForm.ntype!='1'">
|
||||
<xm-question-mng v-if="activateTabPaneName=='41' && editForm.menuId" :xm-product="editForm.productId?{id:editForm.productId,productName:editForm.productName}:null" :xm-menu="editForm.menuId?{menuId:editForm.menuId,menuName:editForm.menuName}:null" :sel-project="xmProject" />
|
||||
@@ -658,32 +658,7 @@ import { MdpFormMixin } from '@/components/mdp-ui/mixin/MdpFormMixin';
|
||||
}
|
||||
toPayAtObj.total=toPayAt;
|
||||
return toPayAtObj;
|
||||
},
|
||||
|
||||
subWorkItemNumCpd(){
|
||||
if(this.subWorkItemNum>0){
|
||||
return this.subWorkItemNum
|
||||
}else{
|
||||
if(this.editForm.ntype=='1'){
|
||||
return this.editForm.childrenCnt
|
||||
}else{
|
||||
return this.subWorkItemNum
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
subPlanNumCpd(){
|
||||
if(this.subPlanNum>0){
|
||||
return this.subPlanNum
|
||||
}else{
|
||||
if(this.editForm.ntype=='1'){
|
||||
return this.editForm.childrenCnt
|
||||
}else{
|
||||
return this.subPlanNum
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
},
|
||||
xmProjectCpd(){
|
||||
if(this.xmProject && this.xmProject.id){
|
||||
return this.xmProject
|
||||
@@ -783,14 +758,7 @@ import { MdpFormMixin } from '@/components/mdp-ui/mixin/MdpFormMixin';
|
||||
}//end return
|
||||
},//end data
|
||||
methods: {
|
||||
...util,
|
||||
setSubWorkItemNum(val){
|
||||
this.subWorkItemNum=val.total;
|
||||
},
|
||||
|
||||
setSubPlanNum(val){
|
||||
this.subPlanNum=val.total;
|
||||
},
|
||||
...util,
|
||||
// 取消按钮点击 父组件监听@cancel="editFormVisible=false" 监听
|
||||
handleCancel:function(){
|
||||
this.$emit('cancel');
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
</el-space>
|
||||
</ContentWrap>
|
||||
|
||||
<el-table element-loading-text="努力加载中" element-loading-spinner="loading" :data="tableDatas"
|
||||
<el-table ref="table" element-loading-text="努力加载中" element-loading-spinner="loading" :data="tableDatas"
|
||||
@sort-change="sortChange" v-loading="load.list" @row-click="rowClick" @selection-change="selsChange"
|
||||
highlight-current-row current-row-key="id" stripe fit border tooltip-effect="light" v-adaptive="{ bottom: 50 }"
|
||||
row-key="id">
|
||||
@@ -118,15 +118,25 @@
|
||||
</el-table-column>
|
||||
<el-table-column sortable prop="rate" label="进度" width="120">
|
||||
<template #default="scope">
|
||||
<el-link v-if="scope.row.ntype == '0'" style="border-radius: 30px"
|
||||
:type="scope.row.rate >= 100 ? 'success' : 'warning'" @click="showWorkload(scope.row)">
|
||||
{{ (scope.row.rate != null ? scope.row.rate : 0) + "%" }}
|
||||
</el-link>
|
||||
|
||||
<el-link v-else style="border-radius: 30px" :type="scope.row.rate >= 100 ? 'success' : 'warning'"
|
||||
@click="calcProgress(scope.row)">
|
||||
{{ (scope.row.rate != null ? scope.row.rate : 0) + "%" }}
|
||||
</el-link>
|
||||
<MdpField>
|
||||
<template #info>
|
||||
<el-link
|
||||
:type="scope.row.rate >= 100 ? 'success' : 'warning'">
|
||||
{{ (scope.row.rate != null ? scope.row.rate : 0) + "%" }}
|
||||
</el-link>
|
||||
</template>
|
||||
|
||||
<template #oper>
|
||||
<el-button type="primary" @click="showWorkload(scope.row)" v-if="scope.row.ntype=='0'" plain>
|
||||
报工
|
||||
</el-button>
|
||||
|
||||
<el-button type="primary" @click="calcProgress(scope.row)" v-if="scope.row.ntype>'0'" plain title="注意仅统计当前计划及上级所有计划的进度情况,不对子计划进行统计">
|
||||
统计进度
|
||||
</el-button>
|
||||
</template>
|
||||
</MdpField>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column sortable prop="createUsername" label="负责人" min-width="120" >
|
||||
@@ -192,6 +202,11 @@
|
||||
{{ scope.row.menuName||scope.row.menuId }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="id" label="编号" width="80" show-overflow-tooltip/>
|
||||
<el-table-column prop="preTaskid" label="前置任务编号" width="80" show-overflow-tooltip/>
|
||||
<el-table-column prop="pidPaths" label="路径" width="80" show-overflow-tooltip/>
|
||||
<el-table-column prop="parentTaskid" label="上级编号" width="80" show-overflow-tooltip/>
|
||||
<el-table-column prop="parentTaskname" label="上级名称" width="80" show-overflow-tooltip/>
|
||||
<template v-if="currOpType=='select' && multiple!=true">
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="scope">
|
||||
@@ -220,22 +235,30 @@
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
|
||||
<mdp-dialog ref="workloadInitDlg" width="600px" append-to-body>
|
||||
<mdp-dialog ref="workloadInitDlg" width="600px" append-to-body title="更新预估工作量">
|
||||
<el-form class="padding" ref="workloadInit" :model="editForm" label-position="top" label-width="80px" >
|
||||
<el-form-item label="更新范围">
|
||||
<div v-if="sels.length == 0">
|
||||
<el-text type="primary" v-if="sels.length == 0">
|
||||
{{ editForm.name }}
|
||||
</div>
|
||||
<div v-if="sels.length > 0">
|
||||
{{ editForm.name }} <font color="red">等{{ sels.length }}个任务</font>
|
||||
</div>
|
||||
</el-text>
|
||||
<el-text v-if="sels.length > 0">
|
||||
{{ editForm.name }} 等{{ sels.length }}个计划/任务
|
||||
</el-text>
|
||||
</el-form-item>
|
||||
<el-form-item label="预估工时(小时)">
|
||||
<el-input style="width:50%;" v-model="editForm.budgetWorkload"
|
||||
@change="editSomeFields(editForm, 'budgetWorkload', $event)" />
|
||||
<el-input v-model="editForm.budgetWorkload" type="number">
|
||||
<template #suffix>
|
||||
小时
|
||||
</template>
|
||||
</el-input>
|
||||
<el-text type="danger">注意:更新范围内的计划/任务的预估工时都会被更新为 {{editForm.budgetWorkload}}小时</el-text>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
|
||||
<el-button @click="Object.assign(editForm,dataBak);$refs['workloadInitDlg'].close()">取消</el-button>
|
||||
<el-button @click="editSomeFields(editForm, 'budgetWorkload', $event)">确定</el-button>
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
<!-- 新增 XmTask xm_task界面-->
|
||||
<mdp-dialog class="XmTaskAdd" title="新增任务" v-model="addFormVisible" width="90%" top="20px" append-to-body
|
||||
@@ -685,7 +708,7 @@ export default {
|
||||
this.menuVisible = false;
|
||||
},
|
||||
onTaskTemplatesSelected(taskTemplates) {
|
||||
debugger
|
||||
|
||||
if (taskTemplates == null || taskTemplates.length == 0) {
|
||||
this.taskTemplateVisible = false;
|
||||
return;
|
||||
@@ -1119,7 +1142,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
var params = { taskIds: this.sels.map(i => i.id), parentTaskid: task.id }
|
||||
var params = this.sels.map(i =>{ return {id:i.id,parentTaskid: task.id}})
|
||||
this.$confirm("确认批量更新以下" + this.sels.length + "个任务的上级为【" + task.name + "】吗?", "提示", {
|
||||
type: "warning",
|
||||
}).then(() => {
|
||||
@@ -1175,50 +1198,4 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped> .extra {
|
||||
border-bottom: 1px solid #dedede;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.field-label {
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.task-header {
|
||||
border-top: 1px solid #dedede;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.compact {
|
||||
font-size: 12px;
|
||||
color: #8c92a4;
|
||||
}
|
||||
|
||||
.compact>span {
|
||||
color: #00b2f3;
|
||||
}
|
||||
|
||||
.remarks {
|
||||
margin-top: 10px;
|
||||
font-size: 16px;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
|
||||
>>>.el-date-editor--daterange.el-input,
|
||||
.el-date-editor--daterange.el-input__inner,
|
||||
.el-date-editor--timerange.el-input,
|
||||
.el-date-editor--timerange.el-input__inner {
|
||||
width: 250px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<el-menu-item :index="'/xm/test/view/env?casedbId='+testCasedb.id">
|
||||
<template #title><i class="setting"></i>环境变量</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item :index="'/xm/test/view/rpt?casedbId='+testCasedb.id">
|
||||
<el-menu-item :index="'/xm/pro/test/view/rpt?casedbId='+testCasedb.id">
|
||||
<template #title><i class="time"></i>统计分析</template>
|
||||
</el-menu-item>
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ export default {
|
||||
methods: {
|
||||
|
||||
initCurrData: function () {
|
||||
debugger
|
||||
|
||||
this.editForm=this.xmTestPlan
|
||||
},
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<template>
|
||||
|
||||
<el-row class="padding" ref="table">
|
||||
|
||||
<el-row class="row_1" style="margin-bottom:20px;">
|
||||
<div class="r r1">
|
||||
<span style="color: #4779F6">{{formatNum(xmBranch.projectCnt,0) || 0}}</span>
|
||||
@@ -64,8 +63,8 @@
|
||||
<el-row style="margin-bottom:20px">
|
||||
<el-col :span="8">
|
||||
<div class="item">
|
||||
<div class="icon1" style="background-color: rgb(79, 140, 255);">
|
||||
<i class="right"></i>
|
||||
<div class="icon1" style="background-color: rgb(79, 140, 255);">
|
||||
<icon icon="ep:right"/>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div v-text="totalTask" ></div>
|
||||
@@ -77,6 +76,7 @@
|
||||
<div class="item">
|
||||
<div class="icon1" style="background-color: rgb(255, 153, 51);">
|
||||
<i class="loading"></i>
|
||||
<icon icon="ep:right"/>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div v-text="notStart" ></div>
|
||||
@@ -88,6 +88,7 @@
|
||||
<div class="item">
|
||||
<div class="icon1" style="background-color: rgb(0, 153, 51);">
|
||||
<i class="check"></i>
|
||||
<icon icon="ep:right"/>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div v-text="competeTasks" ></div>
|
||||
@@ -100,17 +101,17 @@
|
||||
<div class="item">
|
||||
<div class="icon2" style="background-color: rgb(204, 204, 204);">
|
||||
<i class="date"></i>
|
||||
<icon icon="ep:calendar"/>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div v-text="xmBranch.calcTime" ></div>
|
||||
<div class="title">企业数据更新日期</div>
|
||||
<div class="info">
|
||||
<div class="title">更新日期 {{ xmBranch.calcTime }} </div>
|
||||
</div>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-row style="margin-bottom:20px">
|
||||
<div class="item">
|
||||
<div class="icon2" style="background-color: rgb(204, 204, 204);">
|
||||
<i class="star-off"></i>
|
||||
<div class="icon2" style="background-color: rgb(204, 204, 204);">
|
||||
<icon icon="ep:star"/>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title"> 需求数: {{this.xmBranch.menuCnt||0}}</div>
|
||||
@@ -119,8 +120,8 @@
|
||||
</el-row>
|
||||
<el-row style="margin-bottom:20px">
|
||||
<div class="item">
|
||||
<div class="icon2" style="background-color: rgb(204, 204, 204);">
|
||||
<i class="alarm-clock"></i>
|
||||
<div class="icon2" style="background-color: rgb(204, 204, 204);">
|
||||
<icon icon="ep:clock"/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="progress-item">
|
||||
@@ -156,76 +157,70 @@
|
||||
<div id="iterationAndProduct" :style="{width: '100%', height: '350px'}" ></div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" style="margin-bottom:10px">
|
||||
</el-col>
|
||||
<el-col :span="16" >
|
||||
<el-card class="box-card" style="padding:0px ;height:425px">
|
||||
<template #header>
|
||||
<span>企业工时</span>
|
||||
</template >
|
||||
<div>
|
||||
<el-row >
|
||||
<div class="item">
|
||||
<el-row class="item">
|
||||
<el-col :span="8">
|
||||
<div>
|
||||
<div style="text-align:center;">
|
||||
<span style="font-size:24px;" v-text="this.xmBranch.budgetWorkload" ></span>
|
||||
<span style="font-size:5px;">h</span>
|
||||
<span style="font-size:14px;">h</span>
|
||||
</div>
|
||||
<div style="text-align:center;font-size:5px;">总估工时</div>
|
||||
<div style="text-align:center;font-size:14px;">总估工时</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div>
|
||||
<div style="text-align:center;">
|
||||
<span style="font-size:24px;" v-text="this.xmBranch.estimateWorkload" ></span>
|
||||
<span style="font-size:5px;">h</span>
|
||||
<span style="font-size:14px;">h</span>
|
||||
</div>
|
||||
<div style="text-align:center;font-size:5px;">应完成工时</div>
|
||||
<div style="text-align:center;font-size:14px;">应完成工时</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div>
|
||||
<div style="text-align:center;">
|
||||
<span style="font-size:24px;" v-text="this.xmBranch.actWorkload" ></span>
|
||||
<span style="font-size:5px;">h</span>
|
||||
<span style="font-size:14px;">h</span>
|
||||
</div>
|
||||
<div style="text-align:center;font-size:5px;" title="已登记的工时">已完成工时</div>
|
||||
<div style="text-align:center;font-size:14px;" title="已登记的工时">已完成工时</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row >
|
||||
<div class="item">
|
||||
<el-row class="item">
|
||||
<el-col :span="8">
|
||||
<div title="总估工时-已完成工时">
|
||||
<div style="text-align:center;">
|
||||
<span style="font-size:24px;" v-text="remainWorkload" ></span>
|
||||
<span style="font-size:5px;">h</span>
|
||||
<span style="font-size:14px;">h</span>
|
||||
</div>
|
||||
<div style="text-align:center;font-size:5px;">剩余工时</div>
|
||||
<div style="text-align:center;font-size:14px;">剩余工时</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div title="已完成工时-当前应完成工时">
|
||||
<div style="text-align:center;">
|
||||
<span style="font-size:24px;" v-text="deviation" ></span>
|
||||
<span style="font-size:5px;">h</span>
|
||||
<span style="font-size:14px;">h</span>
|
||||
</div>
|
||||
<div style="text-align:center;font-size:5px;">预估偏差</div>
|
||||
<div style="text-align:center;font-size:14px;">预估偏差</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div title="(已完成工时-当前应完成工时)/ 当前应完成工时">
|
||||
<div style="text-align:center;">
|
||||
<span style="font-size:24px;" v-text="deviationRate" ></span>
|
||||
<span style="font-size:5px;">%</span>
|
||||
<span style="font-size:14px;">%</span>
|
||||
</div>
|
||||
<div style="text-align:center;font-size:5px;">预估偏差率</div>
|
||||
<div style="text-align:center;font-size:14px;">预估偏差率</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<span style="margin-left:20px;" title="应完成工时/总预估工时">预计进度</span>
|
||||
@@ -248,9 +243,7 @@
|
||||
<div id="workloadDistribution" :style="{width: '100%', height: '320px'}" ></div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" style="margin-bottom:10px">
|
||||
</el-col>
|
||||
<el-col :span="8" >
|
||||
<el-card class="box-card" style="height:425px">
|
||||
<template #header>
|
||||
@@ -281,10 +274,7 @@
|
||||
<div id="taskChart" :style="{width: '100%', height: '350px'}" ></div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
<el-row :gutter="10" style="margin-bottom:10px">
|
||||
</el-col>
|
||||
<el-col :span="8" >
|
||||
<el-card class="box-card" style="height:425px">
|
||||
<template #header>
|
||||
@@ -307,7 +297,6 @@
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-row>
|
||||
|
||||
</template>
|
||||
|
||||
458
src/views/xm/pro/fin/XmBudgetCost.vue
Normal file
@@ -0,0 +1,458 @@
|
||||
<template>
|
||||
|
||||
|
||||
<ContentWrap>
|
||||
<el-space wrap>
|
||||
<MdpSelectDept v-model="filters.costCenterId" placeholder="成本中心" title="成本中心"/>
|
||||
|
||||
<XmProjectSelect v-model="filters.projectId" v-if="!projectInfo?.id" :link-product-id="xmProduct?.id" @change2="project=$event" @clear="project=null"/>
|
||||
<MdpSelect title="分组统计" split="," v-model="filters.groupBy" :options="[{id:'cost_center_id',name:'成本中心'},{id:'project_id',name:'项目'},{id:'userid',name:'用户'},{id:'subject_id',name:'资金用途(科目)'},{id:'biz_month',name:'支出月份'},{id:'task_id',name:'任务'},{id:'biz_flow_state',name:'审核状态'}]" multiple placeholder="分组"/>
|
||||
<mdp-date-range start-key="startBizMonth" end-key="endBizMonth" type="monthrange" v-model="filters" value-format="YYYY-MM" format="YYYY-MM" placeholder="统计时间" :clearable="false" />
|
||||
<el-checkbox v-model="chartShow">图表</el-checkbox>
|
||||
<el-checkbox v-model="filters.budgetCost" true-label="1" false-label="">预算/实际比对</el-checkbox>
|
||||
<el-button @click="doSearch" icon="search" plain/>
|
||||
</el-space>
|
||||
</ContentWrap>
|
||||
<el-scrollbar v-adaptive>
|
||||
<div v-if="chartShow" class="row-box">
|
||||
<XmBudgetCostMonthTrend :showParams="false" :showTitle="false" :rptDatas="rptDatas" :cfg="echartRptCfg" class="echart-box" :baseView="baseView" :budgetCost="filters.budgetCost" :id="id" :key="id"/>
|
||||
</div>
|
||||
<el-table
|
||||
:data="sumXmBudgeCostConvert"
|
||||
highlight-current-row
|
||||
v-loading="load.list"
|
||||
border >
|
||||
<el-table-column prop="costCenterId" label="成本中心" min-width="150" v-if="filters.groupBy.indexOf('cost_center_id')>=0">
|
||||
<template #default="scope">
|
||||
<MdpField>
|
||||
<template #info>
|
||||
{{scope.row.costCenterId}}
|
||||
</template>
|
||||
<template #oper>
|
||||
<el-space wrap>
|
||||
<el-button v-if="budgetShow" @click="showXmBudgetRecordDetails(scope.row,'costCenterId')">预算</el-button>
|
||||
<el-button v-if="costShow" @click="showXmCostRecordDetails(scope.row,'costCenterId')">成本</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</MdpField>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="projectId" label="项目编号" min-width="150" v-if="filters.groupBy.indexOf('project_id')>=0">
|
||||
<template #default="scope">
|
||||
<MdpField>
|
||||
<template #info>
|
||||
{{scope.row.projectId}}
|
||||
</template>
|
||||
<template #oper>
|
||||
<el-space wrap>
|
||||
<el-button v-if="budgetShow" @click="showXmBudgetRecordDetails(scope.row,'projectId')">预算</el-button>
|
||||
<el-button v-if="costShow" @click="showXmCostRecordDetails(scope.row,'projectId')">成本</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</MdpField>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="subjectId" label="科目" min-width="100" v-if="filters.groupBy.indexOf('subject_id')>=0">
|
||||
<template #default="scope">
|
||||
<MdpField>
|
||||
<template #info>
|
||||
<MdpSelect showStyle="tag" v-model="scope.row.subjectId" itemCode="projectSubject" disabled/>
|
||||
</template>
|
||||
<template #oper>
|
||||
<el-space wrap>
|
||||
<el-button v-if="budgetShow" @click="showXmBudgetRecordDetails(scope.row,'subjectId')">预算</el-button>
|
||||
<el-button v-if="costShow" @click="showXmCostRecordDetails(scope.row,'subjectId')">成本</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</MdpField>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bizFlowState" label="状态" min-width="100" v-if="filters.groupBy.indexOf('biz_flow_state')>=0">
|
||||
<template #default="scope">
|
||||
<MdpField>
|
||||
<template #info>
|
||||
<MdpSelect showStyle="tag" v-model="scope.row.bizFlowState" itemCode="bizFlowState" disabled/>
|
||||
</template>
|
||||
<template #oper>
|
||||
<el-space wrap>
|
||||
<el-button v-if="budgetShow" @click="showXmBudgetRecordDetails(scope.row,'bizFlowState')">预算</el-button>
|
||||
<el-button v-if="costShow" @click="showXmCostRecordDetails(scope.row,'bizFlowState')">成本</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</MdpField>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="userid" label="姓名" min-width="100" v-if="filters.groupBy.indexOf('userid')>=0">
|
||||
<template #default="scope">
|
||||
<MdpField>
|
||||
<template #info>
|
||||
{{scope.row.username||scope.row.userid}}
|
||||
</template>
|
||||
<template #oper>
|
||||
<el-space wrap>
|
||||
<el-button v-if="budgetShow" @click="showXmBudgetRecordDetails(scope.row,'userid')">预算</el-button>
|
||||
<el-button v-if="costShow" @click="showXmCostRecordDetails(scope.row,'userid')">成本</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</MdpField>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<el-table-column prop="taskId" label="任务编号" min-width="100" v-if="filters.groupBy.indexOf('task_id')>=0">
|
||||
<template #default="scope">
|
||||
<MdpField>
|
||||
<template #info>
|
||||
{{scope.row.taskId}}
|
||||
</template>
|
||||
<template #oper>
|
||||
<el-space wrap>
|
||||
<el-button v-if="budgetShow" @click="showXmBudgetRecordDetails(scope.row,'taskId')">预算</el-button>
|
||||
<el-button v-if="costShow" @click="showXmCostRecordDetails(scope.row,'taskId')">成本</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</MdpField>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<!-- <el-table-column min-width="100" /> -->
|
||||
<el-table-column :prop="month" v-for="month in selYearMonths" :key="month" :label="month" width="120">
|
||||
<template #default="scope">
|
||||
<el-space wrap fill>
|
||||
<el-link v-if="budgetShow" @click="showXmBudgetRecordDetails(scope.row,'bizMonth',month)">¥{{$mdp.toFixed(scope.row["budget"+month],2)}}</el-link>
|
||||
|
||||
<el-link v-if="costShow" type="warning" @click="showXmCostRecordDetails(scope.row,'bizMonth',month)">¥{{$mdp.toFixed(scope.row["cost"+month],2)}}</el-link>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="合计" min-width="80" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-space wrap fill>
|
||||
<el-text v-if="budgetShow">¥{{ $mdp.toFixed(scope.row.budgetMonthsSum,2) }}</el-text>
|
||||
<el-text v-if="costShow" type="warning">¥{{ $mdp.toFixed(scope.row.costMonthsSum,2) }}</el-text>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</el-scrollbar>
|
||||
<mdp-dialog ref="xmBudgetRecordDlg" title="查看预算明细" fullscreen append-to-body :close-on-click-modal="false">
|
||||
<template #default="{visible,data}">
|
||||
<XmBudgetRecord :visible="visible" :params="data.params"/>
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
<mdp-dialog ref="xmCostRecordDlg" title="查看成本明细" fullscreen append-to-body :close-on-click-modal="false">
|
||||
<template #default="{visible,data}">
|
||||
<XmCostRecord :visible="visible" :params="data.params" :selProject="project"/>
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util';//全局公共库
|
||||
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { listSumXmCostRecord } from '@/api/xm/pro/xmCostRecord';
|
||||
import { listSumXmBudgetRecord } from '@/api/xm/pro/xmBudgetRecord';
|
||||
import XmBudgetRecord from '@/views/xm/pro/xmBudgetRecord/Index.vue';
|
||||
import XmCostRecord from '@/views/xm/pro/xmCostRecord/Index.vue';
|
||||
import XmProjectSelect from '@/views/xm/core/components/XmProjectSelect.vue'
|
||||
import XmBudgetCostMonthTrend from '../rpt/project/budgetCostMonthTrend.vue'
|
||||
export default {
|
||||
props:{
|
||||
selProject:null,
|
||||
xmProduct:null,
|
||||
baseView:{
|
||||
type:String,
|
||||
default: 'budget'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore,[
|
||||
'userInfo','roles'
|
||||
]),
|
||||
selYearMonths:function(){
|
||||
if(this.filters.groupBy.indexOf('biz_month')<0){
|
||||
return []
|
||||
}
|
||||
var months=this.$mdp.getMonths(this.filters.startBizMonth,this.filters.endBizMonth)
|
||||
return months.map(k=>this.$mdp.formatDate(k,'YYYY-MM'))
|
||||
},
|
||||
sumXmBudgeCostConvert:function(){
|
||||
var map={};
|
||||
var secMap={};
|
||||
this.sumXmBudgetRecords?.forEach(i=>{
|
||||
let key=this.getRowKey(i);
|
||||
let monthKey=key+"_"+(i.bizMonth||'bm');
|
||||
secMap[monthKey]={...i};
|
||||
map[key]={...i};
|
||||
});
|
||||
//实际的成本计算
|
||||
this.sumXmCostRecords?.forEach(i=>{
|
||||
let key=this.getRowKey(i);
|
||||
let monthKey=key+"_"+(i.bizMonth||'bm');
|
||||
|
||||
if(!map[key]){
|
||||
map[key]={...i}
|
||||
secMap[monthKey]={...i};
|
||||
}
|
||||
if(!secMap[monthKey]){
|
||||
secMap[monthKey]={...i}
|
||||
}
|
||||
map[key].actAt=i.actAt
|
||||
secMap[monthKey].actAt=i.actAt
|
||||
});
|
||||
var list=[];
|
||||
for(var key in map){
|
||||
var row=map[key];
|
||||
var budgetMonthsSum=0;
|
||||
var costMonthsSum=0;
|
||||
if(this.filters.groupBy.indexOf('biz_month')>=0){
|
||||
this.selYearMonths.forEach(i=>{
|
||||
var val=secMap[key+"_"+i];
|
||||
if( val !=null && val !=undefined ){
|
||||
row["budget"+i]=val.budgetAt||0;
|
||||
row["cost"+i]=val.actAt||0
|
||||
}else{
|
||||
row["budget"+i]=0;
|
||||
row["cost"+i]=0
|
||||
}
|
||||
budgetMonthsSum=budgetMonthsSum+(row["budget"+i]||0)
|
||||
costMonthsSum=costMonthsSum+(row["cost"+i]||0)
|
||||
});
|
||||
|
||||
}else{
|
||||
row['budgetMonthsSum']=row.budgetAt||0;
|
||||
row['costMonthsSum']=row.actAt||0;
|
||||
}
|
||||
|
||||
list.push(row);
|
||||
}
|
||||
return list;
|
||||
},
|
||||
budgetShow(){
|
||||
|
||||
if(this.baseView=='budget'){
|
||||
return true
|
||||
}else if(this.filters.budgetCost=='1'){
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
},
|
||||
costShow(){
|
||||
if(this.baseView=='cost'){
|
||||
return true
|
||||
}else if(this.filters.budgetCost=='1'){
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
},
|
||||
id(){
|
||||
return this.$mdp.getCodeKey("rpt",this.filters)
|
||||
},
|
||||
echartRptCfg(){
|
||||
let cfg={
|
||||
id:'xxxxx',
|
||||
title:this.titleCpd(),
|
||||
params:{
|
||||
...this.filters
|
||||
}
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
id(){
|
||||
this.listSumSamt()
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filters: {
|
||||
projectId:'',
|
||||
groupBy:'project_id,biz_month',
|
||||
startBizMonth: '',
|
||||
endBizMonth: '',
|
||||
budgetCost: '1',
|
||||
},
|
||||
load:{ list: false, edit: false, del: false, add: false },//查询中...
|
||||
sumXmBudgetRecords:[],
|
||||
sumXmCostRecords:[],
|
||||
chartShow:true,
|
||||
rptDatas:[],
|
||||
project:null,
|
||||
|
||||
}
|
||||
},//end data
|
||||
methods: {
|
||||
|
||||
titleCpd(){
|
||||
var preName=""
|
||||
if(this.project && this.project.id){
|
||||
if(this.project.name){
|
||||
preName=`项目【${this.project.name}】`
|
||||
}else{
|
||||
preName=`项目【${this.project.id}】`
|
||||
}
|
||||
}else{
|
||||
preName="企业"
|
||||
}
|
||||
var midName=''
|
||||
if(this.budgetCost=='1'){
|
||||
midName="预算与实际成本"
|
||||
}else if(this.baseView=='cost'){
|
||||
midName="成本"
|
||||
}else{
|
||||
midName="预算"
|
||||
}
|
||||
return preName+midName+"每月趋势图"
|
||||
},
|
||||
getRowKey(i){
|
||||
return (i.costCenterId||"")+(i.projectId||"")+"_"+(i.subjectId||"")+"_"+(i.userid||"")+"_"+(i.taskId||"")+"_"+(i.bizFlowState||"");
|
||||
},
|
||||
rowClick: function(row, event, column){
|
||||
this.$emit('row-click',row, event, column);// @row-click="rowClick"
|
||||
},
|
||||
doSearch(){
|
||||
this.listSumSamt()
|
||||
},
|
||||
calcEchartData(res){
|
||||
let budgetData=res.data
|
||||
let costData=res.costData
|
||||
if(this.baseView=='cost'){
|
||||
budgetData=res.budgetData
|
||||
costData=res.data
|
||||
}
|
||||
//he bing shuju
|
||||
let map={}
|
||||
budgetData?.forEach(i=>{
|
||||
|
||||
let key=i.bizMonth ||'bm'
|
||||
if(!map[key]){
|
||||
map[key]={bizMonth:i.bizMonth||'bm',actAt:0,budgetAt:i.budgetAt||0}
|
||||
}else{
|
||||
map[key].budgetAt=(map[key].budgetAt||0)+(i.budgetAt||0)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
costData?.forEach(i=>{
|
||||
let key=i.bizMonth||'bm'
|
||||
if(!map[key]){
|
||||
map[key]={bizMonth:i.bizMonth||'bm',actAt:(i.actAt||0),budgetAt:0}
|
||||
}else{
|
||||
map[key].actAt=(map[key].actAt||0)+(i.actAt||0)
|
||||
}
|
||||
})
|
||||
let list=[]
|
||||
for(var key in map){
|
||||
list.push(map[key])
|
||||
}
|
||||
list.sort(this.sort)
|
||||
debugger
|
||||
return list
|
||||
},
|
||||
listSumSamt:function(){
|
||||
var params={
|
||||
projectId:this.projectInfo?.id||this.filters.projectId||"",
|
||||
groupBy: this.filters.groupBy,
|
||||
startBizMonth: this.filters.startBizMonth,
|
||||
endBizMonth: this.filters.endBizMonth,
|
||||
budgetCost: this.filters.budgetCost
|
||||
}
|
||||
if(!params.groupBy){
|
||||
this.$message.error("分组必须选上")
|
||||
return;
|
||||
}
|
||||
let func=listSumXmBudgetRecord
|
||||
if(this.baseView=='cost'){
|
||||
func=listSumXmCostRecord
|
||||
}
|
||||
func(params).then(res=>{
|
||||
if(res.tips.isOk){
|
||||
if(this.baseView=='cost'){
|
||||
this.sumXmBudgetRecords=res.budgetData;
|
||||
this.sumXmCostRecords=res.data;
|
||||
}else{
|
||||
this.sumXmBudgetRecords=res.data;
|
||||
this.sumXmCostRecords=res.costData;
|
||||
}
|
||||
this.rptDatas=this.calcEchartData(res)
|
||||
|
||||
this.$message.success("查询成功")
|
||||
}else{
|
||||
this.$message.error(res.tips.msg)
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
},
|
||||
|
||||
showXmBudgetRecordDetails:function(row,fieldName,fieldValue){
|
||||
|
||||
var params={}
|
||||
var groupByArr=this.filters.groupBy.split(",")
|
||||
groupByArr.forEach(k=>
|
||||
{
|
||||
|
||||
var field=this.$mdp.toCamel(k)
|
||||
if(field!='bizMonth'){
|
||||
params[field]=row[field]
|
||||
}
|
||||
|
||||
})
|
||||
let filters={startBizMonth:this.filters.startBizMonth,endBizMonth:this.filters.endBizMonth}
|
||||
Object.assign(params,filters)
|
||||
if(fieldValue){
|
||||
params[fieldName]=fieldValue
|
||||
}else{
|
||||
params[fieldName]=row[fieldName]
|
||||
}
|
||||
this.$refs['xmBudgetRecordDlg'].open({params:params})
|
||||
},
|
||||
|
||||
showXmCostRecordDetails:function(row,fieldName,fieldValue){
|
||||
|
||||
var params={}
|
||||
var groupByArr=this.filters.groupBy.split(",")
|
||||
groupByArr.forEach(k=>
|
||||
{
|
||||
|
||||
var field=this.$mdp.toCamel(k)
|
||||
if(field!='bizMonth'){
|
||||
params[field]=row[field]
|
||||
}
|
||||
|
||||
})
|
||||
let filters={startBizMonth:this.filters.startBizMonth,endBizMonth:this.filters.endBizMonth}
|
||||
Object.assign(params,filters)
|
||||
if(fieldValue){
|
||||
params[fieldName]=fieldValue
|
||||
}else{
|
||||
params[fieldName]=row[fieldName]
|
||||
}
|
||||
this.$refs['xmCostRecordDlg'].open({params:params})
|
||||
},
|
||||
|
||||
/**end 自定义函数请在上面加**/
|
||||
},//end methods
|
||||
components: {
|
||||
XmBudgetRecord, XmCostRecord,
|
||||
XmProjectSelect,XmBudgetCostMonthTrend
|
||||
//在下面添加其它组件
|
||||
},
|
||||
mounted() {
|
||||
this.project=this.selProject
|
||||
this.product=this.xmProduct
|
||||
this.filters.startBizMonth=this.$mdp.moment().startOf('year').format("YYYY-MM")
|
||||
this.filters.endBizMonth=this.$mdp.moment().endOf('year').format("YYYY-MM")
|
||||
this.listSumSamt()
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
20
src/views/xm/pro/fin/XmBudgetForProduct.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<XmBudget :xmProduct="xmProduct" v-if="xmProduct?.id" baseView="budget"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { mapState } from 'pinia'
|
||||
import XmBudget from './XmBudgetCost.vue'
|
||||
import { useXmStore } from '@/store/modules/xm';
|
||||
export default {
|
||||
computed: {
|
||||
...mapState(useXmStore,['xmProduct']),
|
||||
},
|
||||
components: {
|
||||
XmBudget,
|
||||
//在下面添加其它组件
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
20
src/views/xm/pro/fin/XmBudgetForProject.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<XmBudget :selProject="projectInfo" v-if="projectInfo?.id" baseView="budget"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { mapState } from 'pinia'
|
||||
import XmBudget from './XmBudgetCost.vue'
|
||||
import { useXmStore } from '@/store/modules/xm';
|
||||
export default {
|
||||
computed: {
|
||||
...mapState(useXmStore,['projectInfo']),
|
||||
},
|
||||
components: {
|
||||
XmBudget,
|
||||
//在下面添加其它组件
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
20
src/views/xm/pro/fin/XmCost.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<XmCost baseView="cost"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { mapState } from 'pinia'
|
||||
import XmCost from './XmBudgetCost.vue'
|
||||
import { useXmStore } from '@/store/modules/xm';
|
||||
export default {
|
||||
computed: {
|
||||
...mapState(useXmStore,['xmProduct']),
|
||||
},
|
||||
components: {
|
||||
XmCost,
|
||||
//在下面添加其它组件
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
20
src/views/xm/pro/fin/XmCostForProduct.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<XmCost :xmProduct="xmProduct" v-if="xmProduct?.id" baseView="cost"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { mapState } from 'pinia'
|
||||
import XmCost from './XmBudgetCost.vue'
|
||||
import { useXmStore } from '@/store/modules/xm';
|
||||
export default {
|
||||
computed: {
|
||||
...mapState(useXmStore,['xmProduct']),
|
||||
},
|
||||
components: {
|
||||
XmCost,
|
||||
//在下面添加其它组件
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
19
src/views/xm/pro/fin/XmCostForProject.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<XmCost :selProject="projectInfo" v-if="projectInfo?.id" baseView="cost"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { mapState } from 'pinia'
|
||||
import XmCost from './XmBudgetCost.vue'
|
||||
import { useXmStore } from '@/store/modules/xm';
|
||||
export default {
|
||||
computed: {
|
||||
...mapState(useXmStore,['projectInfo']),
|
||||
},
|
||||
components: {
|
||||
XmCost,
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -1,359 +0,0 @@
|
||||
<template>
|
||||
|
||||
<el-row class="xm-budget">
|
||||
<div class="title-bar">
|
||||
<el-radio-group v-model="costShow" size="medium">
|
||||
<el-radio-button label="预算清单" />
|
||||
<el-radio-button label="预算统计" />
|
||||
</el-radio-group>
|
||||
<span style="margin-left:10px;font-size:14px;">项目总预算:</span> <el-tag type="success">{{projectInfoBudget.planTotalCost}}</el-tag>
|
||||
<span style="margin-left:10px;font-size:14px;">非人力总预算:</span><el-tag>{{projectInfoBudget.planNouserAt}}</el-tag>
|
||||
<span style="margin-left:10px;font-size:14px;">内部人力总预算:</span><el-tag>{{projectInfoBudget.planIuserAt}}</el-tag>
|
||||
<span style="margin-left:10px;font-size:14px;">外购人力总预算:</span><el-tag>{{projectInfoBudget.planOuserAt}}</el-tag>
|
||||
</div>
|
||||
<div class="title-bar">
|
||||
<el-radio-group v-model="showType" size="medium">
|
||||
<el-radio-button label="人力" />
|
||||
<el-radio-button label="非人力" />
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div v-if="costShow == '预算统计'">
|
||||
<el-date-picker style="padding:10px;width:120px;" v-model="selYear" value-format="yyyy" type="year" placeholder="年份" :clearable="false" />
|
||||
<!-- <el-select style="height:50px;padding:10px;width:120px;" v-model="selYear" placeholder="年份">
|
||||
<el-option
|
||||
v-for="item in subjectYearList"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item" />
|
||||
</el-select> -->
|
||||
<el-table
|
||||
ref="table"
|
||||
v-adaptive="{bottom:30}"
|
||||
v-if="showType == '人力'"
|
||||
:data="sumXmBudgetLaborsConvert"
|
||||
highlight-current-row
|
||||
v-loading="load.list"
|
||||
border>
|
||||
<el-table-column prop="subjectId" label="科目" min-width="100" >
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showCostUserDetails(scope.row,'subjectId','queryBySubjectId')">{{scope.row.subjectId}}</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="username" label="姓名" min-width="100" >
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showCostUserDetails(scope.row,'username','queryByUsername')">{{scope.row.username}}</a>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<!-- <el-table-column min-width="100" /> -->
|
||||
<el-table-column :prop="month" v-for="month in selYearMonths" :key="month" :label="month" width="120">
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showCostUserDetails(scope.row,month,'queryByBizzMonth')">{{scope.row[month]}}</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="monthsSum" label="合计" min-width="80"/>
|
||||
</el-table>
|
||||
|
||||
<el-table
|
||||
ref="table"
|
||||
v-adaptive="{bottom:30}"
|
||||
v-if="showType == '非人力'"
|
||||
:data="sumXmBudgetNlaborsConvert"
|
||||
highlight-current-row
|
||||
v-loading="load.list"
|
||||
border
|
||||
style="width: 100%;height:720px;overflow-y:auto;">
|
||||
<el-table-column prop="subjectId" label="科目" min-width="100" >
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showCostNouserDetails(scope.row,'subjectId','queryBySubjectId')">{{scope.row.subjectId}}</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="username" label="姓名" min-width="100" >
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showCostNouserDetails(scope.row,'username','queryByUsername')">{{scope.row.username}}</a>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<!-- <el-table-column min-width="100" /> -->
|
||||
<el-table-column :prop="month" v-for="month in selYearMonths" :key="month" :label="month" width="120">
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showCostNouserDetails(scope.row,month,'queryByBizzMonth')">{{scope.row[month]}}</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="monthsSum" label="合计" min-width="80"/>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<xm-budget-labor v-if="showType == '人力'" :sel-project="projectInfo" />
|
||||
<xm-budget-nlabor v-else :sel-project="projectInfo" />
|
||||
</div>
|
||||
<mdp-dialog title="查看人力预算明细" v-model="xmBudgetLaborVisible" fullscreen append-to-body :close-on-click-modal="false">
|
||||
<xm-budget-labor :xm-budget-labor="xmBudgetLabor" :visible="xmBudgetLaborVisible" :field-name="fieldName" :query-type="queryType" :sel-project="projectInfo" />
|
||||
</mdp-dialog>
|
||||
<mdp-dialog title="查看非人力预算明细" v-model="xmBudgetNlaborVisible" fullscreen append-to-body :close-on-click-modal="false">
|
||||
<xm-budget-nlabor :xm-budget-nlabor="xmBudgetNlabor" :visible="xmBudgetNlaborVisible" :field-name="fieldName" :query-type="queryType" :sel-project="projectInfo" />
|
||||
</mdp-dialog>
|
||||
</el-row>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util';//全局公共库
|
||||
//import Sticky from '@/components/Sticky' // 粘性header组件
|
||||
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { editBudget } from '@/api/xm/core/xmProject';
|
||||
import { listSumXmBudgetLabor } from '@/api/xm/pro/xmBudgetLabor';
|
||||
import { listSumXmBudgetNlabor } from '@/api/xm/pro/xmBudgetNlabor';
|
||||
import xmBudgetLabor from '../xmBudgetLabor/XmBudgetLaborMng.vue';
|
||||
import xmBudgetNlabor from '../xmBudgetNlabor/XmBudgetNlaborMng.vue';
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapState(useUserStore,[
|
||||
'userInfo','roles','projectInfo'
|
||||
]),
|
||||
selYearMonths:function(){
|
||||
var selYear=this.selYear;
|
||||
var yearMonths=[selYear+'-01',selYear+'-02',selYear+'-03',selYear+'-04',selYear+'-05',selYear+'-06',selYear+'-07',selYear+'-08',selYear+'-09',selYear+'-10',selYear+'-11',selYear+'-12']
|
||||
return yearMonths;
|
||||
},
|
||||
sumXmBudgetLaborsConvert:function(){
|
||||
var map={};
|
||||
var secMap={};
|
||||
this.sumXmBudgetLabors.forEach(i=>{
|
||||
i.key=i.projectId+"_"+i.subjectId+"_"+i.userid+"_"+i.username;
|
||||
i.monthKey=i.key+"_"+i.bizzMonth;
|
||||
secMap[i.monthKey]=i;
|
||||
map[i.key]=i;
|
||||
});
|
||||
var list=[];
|
||||
for(var key in map){
|
||||
var row=map[key];
|
||||
var monthsSum=0;
|
||||
this.selYearMonths.forEach(i=>{
|
||||
var val=secMap[key+"_"+i];
|
||||
if( val !=null && val !=undefined ){
|
||||
row[i]=val.budgetCost;
|
||||
}else{
|
||||
row[i]=0;
|
||||
}
|
||||
monthsSum=monthsSum+row[i]
|
||||
});
|
||||
row['monthsSum']=monthsSum;
|
||||
list.push(row);
|
||||
}
|
||||
return list;
|
||||
},
|
||||
sumXmBudgetNlaborsConvert:function(){
|
||||
var map={};
|
||||
var secMap={};
|
||||
this.sumXmBudgetNlabors.forEach(i=>{
|
||||
i.key=i.projectId+"_"+i.subjectId;
|
||||
i.monthKey=i.key+"_"+i.bizzMonth;
|
||||
secMap[i.monthKey]=i;
|
||||
map[i.key]=i;
|
||||
});
|
||||
var list=[];
|
||||
for(var key in map){
|
||||
var row=map[key];
|
||||
var monthsSum=0;
|
||||
this.selYearMonths.forEach(i=>{
|
||||
var val=secMap[key+"_"+i];
|
||||
if( val !=null && val !=undefined ){
|
||||
row[i]=val.budgetCost;
|
||||
}else{
|
||||
row[i]=0;
|
||||
}
|
||||
monthsSum=monthsSum+row[i]
|
||||
});
|
||||
row['monthsSum']=monthsSum;
|
||||
list.push(row);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'showType': function(val) {
|
||||
if(val == "人力"){
|
||||
this.listSumXmBudgetLabor();
|
||||
}
|
||||
else{
|
||||
this.listSumXmBudgetNlabor();
|
||||
}
|
||||
},
|
||||
'projectInfo': function(projectInfo){
|
||||
this.projectInfoBudget=Object.assign({},this.projectInfo);
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filters: {
|
||||
key: ''
|
||||
},
|
||||
screenData: [],//查询结果
|
||||
load:{ list: false, edit: false, del: false, add: false },//查询中...
|
||||
|
||||
/**begin 自定义属性请在下面加 请加备注**/
|
||||
subjects: [],
|
||||
costShow: "预算统计",
|
||||
selYear: ""+new Date().getFullYear(),
|
||||
showType: "",
|
||||
xmBudgetLabors: [],
|
||||
xmBudgetNlabors: [],
|
||||
projectInfoBudget:{},
|
||||
sumXmBudgetLabors:[],
|
||||
xmBudgetLabor:null,
|
||||
fieldName:'',
|
||||
queryType:'',
|
||||
xmBudgetLaborVisible:false,
|
||||
sumXmBudgetNlabors:[],
|
||||
xmBudgetNlabor:null,
|
||||
xmBudgetNlaborVisible:false,
|
||||
tableHeight:300,
|
||||
/**end 自定义属性请在上面加 请加备注**/
|
||||
}
|
||||
},//end data
|
||||
methods: {
|
||||
|
||||
rowClick: function(row, event, column){
|
||||
this.$emit('row-click',row, event, column);// @row-click="rowClick"
|
||||
},
|
||||
|
||||
listSumXmBudgetLabor:function(){
|
||||
var parmas={
|
||||
projectId:this.projectInfo.id,
|
||||
}
|
||||
listSumXmBudgetLabor(parmas).then(res=>{
|
||||
this.sumXmBudgetLabors=res.data;
|
||||
})
|
||||
},
|
||||
|
||||
listSumXmBudgetNlabor:function(){
|
||||
var parmas={
|
||||
projectId:this.projectInfo.id,
|
||||
}
|
||||
listSumXmBudgetNlabor(parmas).then(res=>{
|
||||
this.sumXmBudgetNlabors=res.data;
|
||||
})
|
||||
},
|
||||
showCostUserDetails:function(row,fieldName,queryType){
|
||||
this.xmBudgetLabor=row
|
||||
this.fileName=fieldName
|
||||
this.queryType=queryType
|
||||
this.xmBudgetLaborVisible=true;
|
||||
},
|
||||
showCostNouserDetails:function(row,fieldName,queryType){
|
||||
this.xmBudgetNlabor=row
|
||||
this.fileName=fieldName
|
||||
this.queryType=queryType
|
||||
this.xmBudgetNlaborVisible=true;
|
||||
},
|
||||
/**begin 自定义函数请在下面加**/
|
||||
// inputChange() {
|
||||
// this.projectInfo.planTotalCost = this.projectInfo.planTotalCost.replace(/[^\d.]/g,"").replace(/^\./g,"").replace(/\.{1,}/g,".");
|
||||
// },
|
||||
updateBudget() {
|
||||
if(this.projectInfo.planTotalCost==undefined){
|
||||
this.$notify({position:'bottom-left',showClose:true,message:"不允许修改", type: 'success'});
|
||||
return;
|
||||
}
|
||||
var planTotalCost=this.getFloatValue(this.projectInfoBudget.planTotalCost)
|
||||
var planIuserAt=this.getFloatValue(this.projectInfoBudget.planIuserAt)
|
||||
var planOuserAt=this.getFloatValue(this.projectInfoBudget.planOuserAt)
|
||||
var planNouserAt=this.getFloatValue(this.projectInfoBudget.planNouserAt)
|
||||
this.projectInfoBudget.planTotalCost=planIuserAt+planOuserAt+planNouserAt
|
||||
this.$confirm('确定修改项目总预算吗?', '提示', {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.load.edit = true;
|
||||
let params = this.projectInfoBudget
|
||||
editBudget(params).then((res) => {
|
||||
var tips=res.tips;
|
||||
if(tips.isOk){
|
||||
this.projectInfo.planTotalCost=this.projectInfoBudget.planTotalCost
|
||||
this.projectInfo.planIuserAt=this.projectInfoBudget.planIuserAt
|
||||
this.projectInfo.planOuserAt=this.projectInfoBudget.planOuserAt
|
||||
this.projectInfo.planNouserAt=this.projectInfoBudget.planNouserAt
|
||||
}else{
|
||||
this.projectInfoBudget=Object.assign({},this.projectInfo)
|
||||
}
|
||||
this.$notify({position:'bottom-left',showClose:true,message: tips.msg, type: tips.isOk?'success':'error' });
|
||||
this.load.edit = false;
|
||||
}).catch( err => this.load.edut = false );
|
||||
}).catch(() => {
|
||||
this.projectInfoBudget=Object.assign({},this.projectInfo)
|
||||
});
|
||||
},
|
||||
|
||||
getFloatValue(value,digit){
|
||||
if(value==null || value=='' || value==undefined){
|
||||
value=0;
|
||||
}
|
||||
return parseFloat(value);
|
||||
},
|
||||
/**end 自定义函数请在上面加**/
|
||||
},//end methods
|
||||
components: {
|
||||
xmBudgetLabor,
|
||||
xmBudgetNlabor,
|
||||
//在下面添加其它组件
|
||||
},
|
||||
mounted() {
|
||||
this.showType = "人力";
|
||||
this.projectInfoBudget=Object.assign({},this.projectInfo);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.xm-budget{
|
||||
width: 100%;
|
||||
}
|
||||
.title-bar{
|
||||
padding:7px 10px;
|
||||
height: 50px;
|
||||
background: #fafbfc;
|
||||
border-bottom: 1px solid #efefef;
|
||||
}
|
||||
/* .title-bar>button{
|
||||
float:right;
|
||||
} */
|
||||
.fs-ft{
|
||||
font-size: 14px !important;
|
||||
}
|
||||
.xm-budget .el-form-item{
|
||||
padding: 0 10px;
|
||||
}
|
||||
.xm-budget >>> input[type="number"]{
|
||||
padding-left: 5px;
|
||||
padding-right: 0;
|
||||
}
|
||||
/* .xm-budget >>> .headBorder:first-child, */
|
||||
.xm-budget >>> .headBorder:nth-last-child(3){
|
||||
border-right: 0 !important;
|
||||
}
|
||||
.xm-budget .title-bar >>> .el-radio-button__inner{
|
||||
padding: 10px 15px;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 0 0 0 !important;
|
||||
}
|
||||
.xm-budget .title-bar .is-active >>> .el-radio-button__inner{
|
||||
color: #409EFF !important;
|
||||
border: 1px solid #409EFF;
|
||||
}
|
||||
.xm-budget>.el-table::before{
|
||||
height: 0;
|
||||
}
|
||||
/* 超过宽度则用...代替 */
|
||||
.truncate{
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
@@ -1,370 +0,0 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<el-space wrap>
|
||||
<el-radio-group v-model="showType">
|
||||
<el-radio-button label="人力" />
|
||||
<el-radio-button label="非人力" />
|
||||
</el-radio-group>
|
||||
<XmProjectSelect v-model="filters.projectId" v-if="!projectInfo?.id" />
|
||||
<MdpSelect split="," v-model="filters.groupBy" :options="[{id:'project_id',name:'项目'},{id:'userid',name:'用户'},{id:'subject_id',name:'资金用途(科目)'},{id:'biz_month',name:'支出月份'}]" multiple placeholder="分组"/>
|
||||
<mdp-date v-model="selYear" value-format="YYYY" format="YYYY" type="year" placeholder="统计年份" :clearable="false" />
|
||||
<el-button @click="doSearch" icon="search" plain/>
|
||||
|
||||
</el-space>
|
||||
</ContentWrap>
|
||||
<el-table ref="table"
|
||||
v-adaptive="{bottom:30}"
|
||||
v-if=" showType == '人力'"
|
||||
:data="sumXmCostLaborsConvert"
|
||||
highlight-current-row
|
||||
v-loading="load.list"
|
||||
border>
|
||||
<el-table-column prop="subjectId" label="科目" min-width="100" v-if="filters.groupBy.indexOf('subject_id')>=0">
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showXmCostNlaborDetails(scope.row,'subjectId')">{{scope.row.subjectName||scope.row.subjectId}}</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="userid" label="成员姓名" min-width="100" v-if="filters.groupBy.indexOf('userid')>=0">
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showXmCostLaborDetails(scope.row,'userid')">{{scope.row.username}}</a>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<el-table-column prop="projectId" label="项目编号" min-width="100" v-if="filters.groupBy.indexOf('project_id')>=0">
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showXmCostLaborDetails(scope.row,'projectId')">{{scope.row.projectId}}</a>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<el-table-column prop="branchId" label="企业编号" min-width="100" v-if="filters.groupBy.indexOf('branchId')>=0">
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showXmCostLaborDetails(scope.row,'branchId')">{{scope.row.branchId}}</a>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<!-- <el-table-column min-width="100" /> -->
|
||||
<el-table-column :prop="month" v-for="month in selYearMonths" :key="month" :label="month" width="120">
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showXmCostLaborDetails(scope.row,'bizMonth',month)">¥{{scope.row[month]}}</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="monthsSum" label="合计" min-width="80" fixed="right"/>
|
||||
</el-table>
|
||||
|
||||
<el-table
|
||||
|
||||
v-adaptive="{bottom:30}"
|
||||
v-if=" showType == '非人力'"
|
||||
:data="sumXmCostNlaborsConvert"
|
||||
highlight-current-row
|
||||
v-loading="load.list"
|
||||
border
|
||||
style="width: 100%;height:720px;overflow-y:auto;">
|
||||
<el-table-column prop="subjectId" label="科目" min-width="100" v-if="filters.groupBy.indexOf('subject_id')>=0">
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showXmCostNlaborDetails(scope.row,'subjectId')">{{scope.row.subjectName||scope.row.subjectId}}</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="userid" label="姓名" min-width="100" v-if="filters.groupBy.indexOf('userid')>=0">
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showXmCostNlaborDetails(scope.row,'userid')">{{scope.row.username}}</a>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<el-table-column prop="projectId" label="项目编号" min-width="100" v-if="filters.groupBy.indexOf('project_id')>=0">
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showXmCostNlaborDetails(scope.row,'projectId')">{{scope.row.projectId}}</a>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<!-- <el-table-column min-width="100" /> -->
|
||||
<el-table-column :prop="month" v-for="month in selYearMonths" :key="month" :label="month" width="120">
|
||||
<template #default="scope">
|
||||
<a style="text-decoration:underline;margin-right:5px;" @click="showXmCostNlaborDetails(scope.row,'bizMonth',month)">¥{{scope.row[month]}}</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="monthsSum" label="合计" min-width="80" fixed="right"/>
|
||||
</el-table>
|
||||
<mdp-dialog ref="xmCostLaborDlg" title="查看人力支出明细" width="80%" append-to-body :close-on-click-modal="false">
|
||||
<template #default="{visible,data}">
|
||||
<xm-cost-labor :visible="visible" :params="data.params"/>
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
<mdp-dialog ref="xmCostNlaborDlg" title="查看非人力支出明细" width="90%" append-to-body :close-on-click-modal="false">
|
||||
<template #default="{visible,data}">
|
||||
<xm-cost-nlabor :params="data.params" :visible="visible" :sel-project="projectInfo" />
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util';//全局公共库
|
||||
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { useXmStore } from '@/store/modules/xm';
|
||||
import { listSumXmCostLabor } from '@/api/xm/pro/xmTaskSbillDetail';
|
||||
import { listSumXmCostNlabor } from '@/api/xm/pro/xmCostNlabor';
|
||||
import xmCostLabor from '@/views/xm/pro/xmTaskSbillDetail/XmTaskSbillDetailMng.vue';
|
||||
import xmCostNlabor from '@/views/xm/pro/xmCostNlabor/XmCostNlaborMng.vue';
|
||||
import XmProjectSelect from '@/views/xm/core/components/XmProjectSelect.vue'
|
||||
export default {
|
||||
computed: {
|
||||
...mapState(useUserStore,[
|
||||
'userInfo','roles'
|
||||
]),
|
||||
...mapState(useXmStore,[ 'projectInfo']),
|
||||
selYearMonths:function(){
|
||||
var selYear=this.selYear||'未知';
|
||||
var yearMonths=[selYear+'-01',selYear+'-02',selYear+'-03',selYear+'-04',selYear+'-05',selYear+'-06',selYear+'-07',selYear+'-08',selYear+'-09',selYear+'-10',selYear+'-11',selYear+'-12']
|
||||
return yearMonths;
|
||||
},
|
||||
sumXmCostLaborsConvert:function(){
|
||||
var map={};
|
||||
var secMap={};
|
||||
this.sumXmCostLabors.forEach(i=>{
|
||||
i.key=i.branchId+"_"+i.projectId+"_"+i.subjectId+"_"+i.userid;
|
||||
i.monthKey=i.key+"_"+i.bizMonth;
|
||||
secMap[i.monthKey]=i;
|
||||
map[i.key]=i;
|
||||
});
|
||||
var list=[];
|
||||
for(var key in map){
|
||||
var row=map[key];
|
||||
var monthsSum=0;
|
||||
this.selYearMonths.forEach(i=>{
|
||||
var val=secMap[key+"_"+i];
|
||||
if( val !=null && val !=undefined ){
|
||||
row[i]=val.samt;
|
||||
}else{
|
||||
row[i]=0;
|
||||
}
|
||||
monthsSum=monthsSum+row[i]
|
||||
});
|
||||
row['monthsSum']=monthsSum;
|
||||
list.push(row);
|
||||
}
|
||||
return list;
|
||||
},
|
||||
sumXmCostNlaborsConvert:function(){
|
||||
var map={};
|
||||
var secMap={};
|
||||
this.sumXmCostNlabors.forEach(i=>{
|
||||
i.key=i.projectId+"_"+i.subjectId;
|
||||
i.monthKey=i.key+"_"+i.bizMonth;
|
||||
secMap[i.monthKey]=i;
|
||||
map[i.key]=i;
|
||||
});
|
||||
var list=[];
|
||||
for(var key in map){
|
||||
var row=map[key];
|
||||
var monthsSum=0;
|
||||
this.selYearMonths.forEach(i=>{
|
||||
var val=secMap[key+"_"+i];
|
||||
if( val !=null && val !=undefined ){
|
||||
row[i]=val.actAt;
|
||||
}else{
|
||||
row[i]=0;
|
||||
}
|
||||
monthsSum=monthsSum+row[i]
|
||||
});
|
||||
row['monthsSum']=monthsSum;
|
||||
list.push(row);
|
||||
}
|
||||
return list;
|
||||
},
|
||||
keyCpd(){
|
||||
return this.showType+"|"+this.selYear+"|"+this.rptType+"|"+(this.projectInfo?.id||'')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
keyCpd: function(){
|
||||
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filters: {
|
||||
projectId:'',
|
||||
groupBy:'project_id,biz_month',
|
||||
startBizMonth: '',
|
||||
endBizMonth: ''
|
||||
},
|
||||
screenData: [],//查询结果
|
||||
load:{ list: false, edit: false, del: false, add: false },//查询中...
|
||||
|
||||
/**begin 自定义属性请在下面加 请加备注**/
|
||||
subjects: [],
|
||||
costShow: "支出统计",
|
||||
selYear: ""+new Date().getFullYear(),
|
||||
showType: "人力",
|
||||
xmCostLabor: [],
|
||||
xmCostNlabor: [],
|
||||
sumXmCostLabors:[],
|
||||
fieldName:'',
|
||||
queryType:'',
|
||||
sumXmCostNlabors:[],
|
||||
rptType:'1',//统计类型
|
||||
/**end 自定义属性请在上面加 请加备注**/
|
||||
}
|
||||
},//end data
|
||||
methods: {
|
||||
|
||||
rowClick: function(row, event, column){
|
||||
this.$emit('row-click',row, event, column);// @row-click="rowClick"
|
||||
},
|
||||
doSearch(){
|
||||
if(this.showType=='人力'){
|
||||
this.listSumSamt()
|
||||
}else{
|
||||
this.listSumXmCostNlabor()
|
||||
}
|
||||
},
|
||||
listSumSamt:function(){
|
||||
var params={
|
||||
projectId:this.projectInfo?.id||this.filters.projectId||"",
|
||||
groupBy: this.filters.groupBy,
|
||||
bizYear:this.selYear,
|
||||
}
|
||||
if(!params.groupBy){
|
||||
this.$message.error("分组必须选上")
|
||||
return;
|
||||
}
|
||||
if(params.groupBy.indexOf('biz_month')<0){
|
||||
this.$message.error("分组必须选上支出月份")
|
||||
return;
|
||||
}
|
||||
listSumXmCostLabor(params).then(res=>{
|
||||
if(res.tips.isOk){
|
||||
this.sumXmCostLabors=res.data;
|
||||
this.$message.success("查询成功")
|
||||
}else{
|
||||
this.$message.error(res.tips.msg)
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
},
|
||||
|
||||
listSumXmCostNlabor:function(){
|
||||
var params={
|
||||
projectId:this.projectInfo?.id||this.filters.projectId||"",
|
||||
groupBy: this.filters.groupBy,
|
||||
startBizMonth: this.selYear+"-01",
|
||||
endBizMonth: this.selYear+"-12"
|
||||
}
|
||||
if(!params.groupBy){
|
||||
this.$message.error("分组必须选上")
|
||||
return;
|
||||
}
|
||||
if(params.groupBy.indexOf('biz_month')<0){
|
||||
this.$message.error("分组必须选上支出月份")
|
||||
return;
|
||||
}
|
||||
|
||||
listSumXmCostNlabor(params).then(res=>{
|
||||
if(res.tips.isOk){
|
||||
this.sumXmCostNlabors=res.data;
|
||||
this.$message.success("查询成功")
|
||||
}else{
|
||||
this.$message.error(res.tips.msg)
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
showXmCostLaborDetails:function(row,fieldName,fieldValue){
|
||||
|
||||
var params={}
|
||||
var groupByArr=this.filters.groupBy.split(",")
|
||||
groupByArr.forEach(k=>
|
||||
{
|
||||
var field=this.$mdp.toCamel(k)
|
||||
params[field]=row[field]
|
||||
})
|
||||
if(fieldValue){
|
||||
params[fieldName]=fieldValue
|
||||
}else{
|
||||
params[fieldName]=row[fieldName]
|
||||
}
|
||||
this.$refs['xmCostLaborDlg'].open({params:params})
|
||||
},
|
||||
showXmCostNlaborDetails:function(row,fieldName,fieldValue){
|
||||
var params={}
|
||||
var groupByArr=this.filters.groupBy.split(",")
|
||||
groupByArr.forEach(k=>
|
||||
{
|
||||
var field=this.$mdp.toCamel(k)
|
||||
params[field]=row[field]
|
||||
})
|
||||
if(fieldValue){
|
||||
params[fieldName]=fieldValue
|
||||
}else{
|
||||
params[fieldName]=row[fieldName]
|
||||
}
|
||||
this.$refs['xmCostNlaborDlg'].open({params:params})
|
||||
},
|
||||
/**end 自定义函数请在上面加**/
|
||||
},//end methods
|
||||
components: {
|
||||
xmCostLabor,
|
||||
xmCostNlabor,
|
||||
XmProjectSelect
|
||||
//在下面添加其它组件
|
||||
},
|
||||
mounted() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.xm-cost{
|
||||
width: 100%;
|
||||
}
|
||||
.title-bar{
|
||||
padding:7px 10px;
|
||||
height: 50px;
|
||||
background: #fafbfc;
|
||||
border-bottom: 1px solid #efefef;
|
||||
}
|
||||
/* .title-bar>button{
|
||||
float:right;
|
||||
} */
|
||||
.fs-ft{
|
||||
font-size: 14px !important;
|
||||
}
|
||||
.xm-cost .el-form-item{
|
||||
padding: 0 10px;
|
||||
}
|
||||
.xm-cost >>> input[type="number"]{
|
||||
padding-left: 5px;
|
||||
padding-right: 0;
|
||||
}
|
||||
/* .xm-cost >>> .headBorder:first-child, */
|
||||
.xm-cost >>> .headBorder:nth-last-child(3){
|
||||
border-right: 0 !important;
|
||||
}
|
||||
.xm-cost .title-bar >>> .el-radio-button__inner{
|
||||
padding: 10px 15px;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 0 0 0 !important;
|
||||
}
|
||||
.xm-cost .title-bar .is-active >>> .el-radio-button__inner{
|
||||
color: #409EFF !important;
|
||||
border: 1px solid #409EFF;
|
||||
}
|
||||
.xm-cost>.el-table::before{
|
||||
height: 0;
|
||||
}
|
||||
/* 超过宽度则用...代替 */
|
||||
.truncate{
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
@@ -309,7 +309,7 @@ export default {
|
||||
}
|
||||
},
|
||||
onCompSelect(comp){
|
||||
debugger
|
||||
|
||||
if(this.compCfgList.some(k=>k.compId==comp.compId)){
|
||||
var compCfg=this.compCfgList.find(k=>k.compId==comp.compId)
|
||||
this.$nextTick(()=>{
|
||||
|
||||
@@ -143,6 +143,7 @@ export default {
|
||||
{ isChecked: false, isCurr: false, rptName: '任务排行榜', category: '项目级,企业级', compId: 'xmTaskSort', desc: '任务提出人、负责人的用户故事数量排行(实时数据)', img: bar },
|
||||
{ isChecked: false, isCurr: false, rptName: '项目结算工时每日趋势', category: '项目级', compId: 'xmProjectWorkloadSetDayList', desc: '统计项目每日登记工时、结算工时数量分布情况', img: datasetLink },
|
||||
{ isChecked: false, isCurr: false, rptName: '项目结算工时每月趋势', category: '项目级', compId: 'xmProjectWorkloadSetMonthList', desc: '统计项目每月登记工时、结算工时数量分布情况', img: datasetLink },
|
||||
{ isChecked: false, isCurr: false, rptName: '预算与成本每月趋势', category: '产品级,企业级,项目级', compId: 'xmBudgetCostMonthTrend', desc: '统计每月的预算与实际成本的趋势', img: datasetLink },
|
||||
|
||||
|
||||
//测试库级报表
|
||||
|
||||
@@ -24,6 +24,7 @@ export default {
|
||||
xmProjectWorkItemDayList:defineAsyncComponent(()=>import("../project/projectWorkItemDayList.vue")),
|
||||
xmProjectWorkloadSetDayList:defineAsyncComponent(()=>import("../project/projectWorkloadSetDayList.vue")),
|
||||
xmProjectWorkloadSetMonthList:defineAsyncComponent(()=>import("../project/projectWorkloadSetMonthList.vue")),
|
||||
xmBudgetCostMonthTrend:defineAsyncComponent(()=>import("../project/budgetCostMonthTrend.vue")),
|
||||
|
||||
xmQuestionDayTrend:defineAsyncComponent(()=>import("../product/questionDayTrend.vue")),
|
||||
xmQuestionDayAccumulate:defineAsyncComponent(()=>import("../product/questionDayAccumulate.vue")),
|
||||
|
||||
315
src/views/xm/pro/rpt/project/budgetCostMonthTrend.vue
Normal file
@@ -0,0 +1,315 @@
|
||||
<template>
|
||||
<MdpRptHeader v-model:title="title" v-model:remark="remark" :isRptCfg="isRptCfg" :showParams="showParams" @delete="$emit('delete',cfg)">
|
||||
<template #title v-if="showTitle===false">
|
||||
<span></span>
|
||||
</template>
|
||||
<el-form :model="params" class="padding" ref="filtersRef">
|
||||
<el-form-item label="归属项目">
|
||||
<XmProjectSelect width="100%" v-model="params.projectId" v-if="!projectInfo?.id" :linkProductId="xmProduct?.id" @change2="project=$event"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="分组">
|
||||
<MdpSelect width="100%" title="分组统计" split="," v-model="params.groupBy" :options="[{id:'cost_center_id',name:'成本中心'},{id:'project_id',name:'项目'},{id:'userid',name:'用户'},{id:'subject_id',name:'资金用途(科目)'},{id:'biz_month',name:'支出月份'},{id:'task_id',name:'任务'},{id:'biz_flow_state',name:'审核状态'}]" multiple placeholder="分组"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="月份区间">
|
||||
<mdp-date-range start-key="startBizMonth" end-key="endBizMonth" type="monthrange" v-model="params" value-format="YYYY-MM" format="YYYY-MM" placeholder="统计时间" :clearable="false" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #toolbar>
|
||||
<el-button type="primary" icon="search" @click="listSumXmBudgetRecord">查询</el-button>
|
||||
</template>
|
||||
</MdpRptHeader>
|
||||
<div class="row-box">
|
||||
<div class="echart-box" :id="this.id"></div>
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util';//全局公共库
|
||||
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
|
||||
import { listSumXmCostRecord } from '@/api/xm/pro/xmCostRecord';
|
||||
import { listSumXmBudgetRecord } from '@/api/xm/pro/xmBudgetRecord';
|
||||
import XmProjectSelect from '@/views/xm/core/components/XmProjectSelect.vue';//新增界面
|
||||
import * as echarts from 'echarts';
|
||||
export default {
|
||||
|
||||
components: {
|
||||
XmProjectSelect,
|
||||
},
|
||||
props:['id','cfg','category','showToolBar','showParams','isRptCfg','rptDatas','xmProduct','xmProject','baseView'/**cost/budget */,'budgetCost'/**1-预算与成本比对*/,'showTitle'/**true/false */],
|
||||
computed: {
|
||||
...mapState(useUserStore,[
|
||||
'userInfo','roles'
|
||||
]),
|
||||
monthsCpd(){
|
||||
if(this.rawDatas.length==0){
|
||||
return []
|
||||
}else{
|
||||
return this.rawDatas.map(i=>(i.bizMonth=="bm"?"合计":i.bizMonth))
|
||||
|
||||
}
|
||||
},
|
||||
budgetAtCpd(){
|
||||
if(this.rawDatas.length==0){
|
||||
return []
|
||||
}else{
|
||||
return this.rawDatas.map(i=>i.budgetAt)
|
||||
}
|
||||
},
|
||||
costAtCpd(){
|
||||
if(this.rawDatas.length==0){
|
||||
return []
|
||||
}else{
|
||||
return this.rawDatas.map(i=> i.actAt)
|
||||
}
|
||||
},
|
||||
|
||||
legendCpd(){
|
||||
if(this.budgetCost=='1'){
|
||||
return ['预算','成本']
|
||||
}else{
|
||||
if(this.baseView=='cost'){
|
||||
return ['成本']
|
||||
}else{
|
||||
return ["预算"]
|
||||
}
|
||||
}
|
||||
},
|
||||
titleCpd(){
|
||||
if(this.cfg?.title){
|
||||
return this.cfg.title
|
||||
}
|
||||
var preName=""
|
||||
if(this.project && this.project.id){
|
||||
if(this.project.name){
|
||||
preName=`项目【${this.project.name}】`
|
||||
}else{
|
||||
preName=`项目【${this.project.id}】`
|
||||
}
|
||||
}else{
|
||||
preName="企业"
|
||||
}
|
||||
var midName=''
|
||||
if(this.budgetCost=='1'){
|
||||
midName="预算与实际成本"
|
||||
}else if(this.baseView=='cost'){
|
||||
midName="成本"
|
||||
}else{
|
||||
midName="预算"
|
||||
}
|
||||
return preName+midName+"每月趋势图"
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
rptDatas(val){
|
||||
this.rawDatas=val
|
||||
},
|
||||
monthsCpd(){
|
||||
|
||||
this.$nextTick(()=>{
|
||||
this.drawCharts();
|
||||
})
|
||||
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
product:null,
|
||||
project:null,
|
||||
params:{
|
||||
budgetCost:'1',
|
||||
groupBy:'project_id,biz_month'
|
||||
},
|
||||
title:'',//报表配置项
|
||||
remark:'', //报表配置项
|
||||
rawDatas:[],
|
||||
|
||||
}//end return
|
||||
},//end data
|
||||
methods: {
|
||||
|
||||
getRowKey(i){
|
||||
return i.bizMonth;
|
||||
},
|
||||
listSumXmBudgetRecord(){
|
||||
if(this.rptDatas){
|
||||
this.rawDatas=this.rptDatas
|
||||
return;
|
||||
}
|
||||
|
||||
var params={...this.params}
|
||||
if(!params.groupBy){
|
||||
this.$message.error("分组必须选上")
|
||||
return;
|
||||
}
|
||||
let func=listSumXmBudgetRecord
|
||||
if(this.baseView=='cost'){
|
||||
func=listSumXmCostRecord
|
||||
}
|
||||
func(params).then(res=>{
|
||||
if(res.tips.isOk){
|
||||
let budgetData=res.data
|
||||
let costData=res.costData
|
||||
if(this.baseView=='cost'){
|
||||
budgetData=res.budgetData
|
||||
costData=res.data
|
||||
}
|
||||
//he bing shuju
|
||||
let map={}
|
||||
budgetData?.forEach(i=>{
|
||||
let key=this.getRowKey(i)||'hj'
|
||||
|
||||
if(!map[key]){
|
||||
map[key]={bizMonth:i.bizMonth,actAt:0,budgetAt:i.budgetAt||0}
|
||||
}else{
|
||||
map[key].budgetAt=(map[key].budgetAt||0)+(i.budgetAt||0)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
costData?.forEach(i=>{
|
||||
let key=this.getRowKey(i)||'hj'
|
||||
if(!map[key]){
|
||||
map[key]={bizMonth:i.bizMonth,actAt:(i.actAt||0),budgetAt:0}
|
||||
}else{
|
||||
map[key].actAt=(map[key].actAt||0)+(i.actAt||0)
|
||||
}
|
||||
})
|
||||
let list=[]
|
||||
for(var key in map){
|
||||
list.push(map[key])
|
||||
}
|
||||
list.sort(this.sort)
|
||||
this.rawDatas=list
|
||||
}else{
|
||||
this.$message.error(res.tips.msg)
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
sort(x,y){
|
||||
let x1=parseInt(x.bizMonth.replace("-",""))
|
||||
let y1=parseInt(y.bizMonth.replace("-",""))
|
||||
return x1-y1
|
||||
},
|
||||
open(){
|
||||
this.product=this.xmProduct
|
||||
this.project=this.xmProject
|
||||
if( this.product && this.product.id){
|
||||
this.params.productId= this.product.id
|
||||
}
|
||||
|
||||
if( this.project && this.project.id){
|
||||
this.params.projectId= this.project.id
|
||||
}
|
||||
if(this.cfg && this.cfg.id){
|
||||
this.params=this.cfg.params
|
||||
this.title=this.cfg.title
|
||||
this.remark=this.cfg.remark
|
||||
}
|
||||
if(this.showToolBar && !this.title){
|
||||
this.title=""
|
||||
}
|
||||
this.$nextTick(()=>{
|
||||
this.listSumXmBudgetRecord();
|
||||
})
|
||||
|
||||
},
|
||||
drawCharts() {
|
||||
this.myChart = echarts.init(document.getElementById(this.id));
|
||||
this.myChart.setOption(
|
||||
{
|
||||
title: {
|
||||
text: this.titleCpd,
|
||||
left: 'center'
|
||||
},
|
||||
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
barMaxWidth: 100,
|
||||
toolbox: {
|
||||
show: true,
|
||||
top:"5%",
|
||||
right:"10px",
|
||||
feature: {
|
||||
dataView: { show: true, readOnly: false },
|
||||
magicType: { show: true, type: ['line', 'bar'] },
|
||||
|
||||
saveAsImage: { show: true }
|
||||
}
|
||||
},
|
||||
|
||||
calculable: true,
|
||||
legend: {
|
||||
bottom: 'bottom',
|
||||
data: this.legendCpd
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: this.monthsCpd
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
|
||||
|
||||
{
|
||||
name:'预算',
|
||||
data: this.budgetAtCpd,
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
// 折点颜色样式
|
||||
color: 'blue',
|
||||
lineStyle: {
|
||||
// 折线颜色样式
|
||||
color: 'blue'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name:'成本',
|
||||
data: this.costAtCpd,
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
// 折点颜色样式
|
||||
color: 'orange',
|
||||
lineStyle: {
|
||||
// 折线颜色样式
|
||||
color: 'orange'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
},
|
||||
},//end method
|
||||
mounted() {
|
||||
this.params.startBizMonth=this.$mdp.moment().startOf('year').format("YYYY-MM")
|
||||
this.params.endBizMonth=this.$mdp.moment().endOf('year').format("YYYY-MM")
|
||||
this.open();
|
||||
|
||||
}//end mounted
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.image {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
@@ -1,159 +0,0 @@
|
||||
<template>
|
||||
|
||||
<el-row class="page-header" />
|
||||
<el-row class="page-main" :style="{overflowX:'auto',height:maxTableHeight+'px'}" ref="table">
|
||||
<!--编辑界面 XmBudgetLabor 项目人力成本预算-->
|
||||
<el-form :model="editForm" label-width="120px" :rules="editFormRules" ref="editFormRef">
|
||||
<el-form-item label="项目编号" prop="projectId">
|
||||
<el-input v-model="editForm.projectId" placeholder="项目编号" :maxlength="50" disabled/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名称" prop="username">
|
||||
<el-input v-model="editForm.username" placeholder="用户,如果不确定具体人员,可用岗位代替" />
|
||||
</el-form-item>
|
||||
<el-form-item label="预算金额/每月" prop="budgetAt">
|
||||
<el-input v-model="editForm.budgetAt" placeholder="预算金额/每月" :maxlength="10"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用途说明" prop="remark">
|
||||
<el-input v-model="editForm.remark" placeholder="备注" />
|
||||
</el-form-item>
|
||||
<el-form-item label="预算科目" prop="subjectId">
|
||||
<mdp-select item-code="projectSubject" placeholder="预算科目编号" v-model="editForm.subjectId"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预算月份" prop="bizMonth">
|
||||
<el-date-picker
|
||||
v-model="editForm.bizMonth"
|
||||
type="month"
|
||||
value-format="yyyy-MM"
|
||||
placeholder="选择年月">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<el-row class="page-bottom bottom-fixed">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button v-loading="load.edit" type="primary" @click="saveSubmit" :disabled="load.edit==true">提交</el-button>
|
||||
</el-row>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util';//全局公共库
|
||||
import config from "@/api/mdp_pub/mdp_config"; //全局公共库import
|
||||
import { addXmBudgetLabor,editXmBudgetLabor } from '@/api/xm/pro/xmBudgetLabor';
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
export default {
|
||||
name:'xmBudgetLaborEdit',
|
||||
components: {
|
||||
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore,[ 'userInfo' ]),
|
||||
|
||||
},
|
||||
props:['xmBudgetLabor','visible','opType'],
|
||||
|
||||
watch: {
|
||||
'xmBudgetLabor':function( xmBudgetLabor ) {
|
||||
if(xmBudgetLabor){
|
||||
this.editForm = {...xmBudgetLabor};
|
||||
}
|
||||
|
||||
},
|
||||
'visible':function(visible) {
|
||||
if(visible==true){
|
||||
this.initData()
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currOpType:'add',//add/edit
|
||||
load:{ list: false, edit: false, del: false, add: false },//查询中...
|
||||
|
||||
editFormRules: {
|
||||
subjectId: [
|
||||
{ required: true, message: '科目不能为空', trigger: 'change' }
|
||||
],
|
||||
username: [
|
||||
{ required: true, message: '姓名不能为空,如果不确定具体人,请填写岗位代替', trigger: 'change' }
|
||||
],
|
||||
budgetAt: [
|
||||
{ required: true, message: '金额不能为空', trigger: 'change' }
|
||||
],
|
||||
|
||||
remark: [
|
||||
{ required: true, message: '用途说明不能为空', trigger: 'change' }
|
||||
]
|
||||
},
|
||||
editForm: {
|
||||
projectId:'',userid:'',budgetAt:'',id:'',remark:'',username:'',subjectId:'',bizSdate:'',bizEdate:'',bizMonth:'',instId:'',bizFlowState:'',costType:'',subjectName:'',branchId:'',ubranchId:''
|
||||
},
|
||||
maxTableHeight:300,
|
||||
}//end return
|
||||
},//end data
|
||||
methods: {
|
||||
|
||||
...util,
|
||||
|
||||
// 取消按钮点击 父组件监听@cancel="editFormVisible=false" 监听
|
||||
handleCancel:function(){
|
||||
this.$refs['editFormRef'].resetFields();
|
||||
this.$emit('cancel');
|
||||
},
|
||||
//新增、编辑提交XmBudgetLabor 项目人力成本预算父组件监听@submit="afterEditSubmit"
|
||||
saveSubmit: function () {
|
||||
this.$refs.editFormRef.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$confirm('确认提交吗?', '提示', {}).then(() => {
|
||||
this.load.edit=true
|
||||
let params = Object.assign({}, this.editForm);
|
||||
var func=addXmBudgetLabor
|
||||
if(this.currOpType=='edit'){
|
||||
func=editXmBudgetLabor
|
||||
}
|
||||
func(params).then((res) => {
|
||||
this.load.edit=false
|
||||
var tips=res.tips;
|
||||
if(tips.isOk){
|
||||
this.editForm=res.data
|
||||
this.initData()
|
||||
this.currOpType="edit";
|
||||
this.$emit('submit');// @submit="afterAddSubmit"
|
||||
}
|
||||
this.$notify({ position:'bottom-left',showClose:true, message: tips.msg, type: tips.isOk?'success':'error' });
|
||||
}).catch( err =>this.load.edit=false);
|
||||
});
|
||||
}else{
|
||||
this.$notify({ showClose:true, message: "表单验证不通过,请修改表单数据再提交", type: 'error' });
|
||||
}
|
||||
});
|
||||
},
|
||||
initData: function(){
|
||||
this.currOpType=this.opType
|
||||
if(this.xmBudgetLabor){
|
||||
this.editForm = Object.assign({},this.xmBudgetLabor);
|
||||
}
|
||||
|
||||
if(this.opType=='edit'){
|
||||
|
||||
}else{
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
},//end method
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initData()
|
||||
//this.maxTableHeight =util.calcTableMaxHeight(this.$refs.table.$el)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped />
|
||||
@@ -1,322 +0,0 @@
|
||||
<template>
|
||||
|
||||
<el-row>
|
||||
<el-input v-model="filters.key" style="width: 20%;" placeholder="模糊查询"/>
|
||||
<el-button v-loading="load.list" :disabled="load.list==true" @click="searchXmBudgetLabors" icon="search">查询</el-button>
|
||||
<span style="float:right;">
|
||||
<el-button type="primary" @click="showAdd" icon="plus" plain/>
|
||||
<el-button type="danger" v-loading="load.del" @click="batchDel" :disabled="this.sels.length===0 || load.del==true" icon="delete" plain/>
|
||||
</span>
|
||||
</el-row>
|
||||
<el-row class="padding-top">
|
||||
<!--列表 XmBudgetLabor 项目人力成本预算-->
|
||||
<el-table ref="xmBudgetLaborTable" :data="xmBudgetLabors" v-adaptive="{bottom:50}" @sort-change="sortChange" highlight-current-row v-loading="load.list" border @selection-change="selsChange" @row-click="rowClick" style="width: 100%;">
|
||||
<el-table-column type="selection" width="55" show-overflow-tooltip fixed="left" />
|
||||
<el-table-column sortable type="index" width="55" show-overflow-tooltip fixed="left" />
|
||||
<!--
|
||||
<el-table-column sortable prop="username" width="55" show-overflow-tooltip fixed="left">
|
||||
<span class="cell-text"> {{scope.row.username}}} </span>
|
||||
<span class="cell-bar"><el-input style="display:inline;" v-model="scope.row.username" placeholder="" @change="editSomeFields(scope.row,'username',$event)" :maxlength="22"/></span>
|
||||
</el-table-column>
|
||||
-->
|
||||
<el-table-column prop="projectId" label="项目编号" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span> {{scope.row.projectId}} </span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="username" label="项目成员" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="cell-text"> {{scope.row.username}} </span>
|
||||
<span class="cell-bar"><el-input style="display:inline;" v-model="scope.row.username" placeholder="" @change="editSomeFields(scope.row,'username',$event)" :maxlength="22"/></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="subjectId" label="预算科目" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<mdp-select item-code="projectSubject" show-style="tag" v-model="scope.row.subjectId" placeholder="预算科目" style="display:block;" @change="editSomeFields(scope.row,'subjectId',$event)"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="用途说明" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="cell-text"> {{scope.row.remark}} </span>
|
||||
<span class="cell-bar"><el-input style="display:inline;" v-model="scope.row.remark" placeholder="" @change="editSomeFields(scope.row,'remark',$event)" :maxlength="22"/></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="budgetAt" label="预算金额" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="cell-text"> {{scope.row.budgetAt}} </span>
|
||||
<span class="cell-bar"><el-input type="number" style="display:inline;" v-model="scope.row.budgetAt" placeholder="" @change="editSomeFields(scope.row,'budgetAt',$event)" :maxlength="22"/></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bizMonth" label="费用月份" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="cell-text"> {{scope.row.bizMonth}} </span>
|
||||
<span class="cell-bar">
|
||||
<el-date-picker
|
||||
@change="editSomeFields(scope.row,'bizMonth',$event)"
|
||||
v-model="scope.row.bizMonth"
|
||||
type="month"
|
||||
value-format="yyyy-MM"
|
||||
placeholder="选择年月" />
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" @click="showEdit( scope.row,scope.$index)" icon="edit" plain/>
|
||||
<el-button type="danger" @click="handleDel(scope.row,scope.$index)" icon="delete" plain/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination layout="total, sizes, prev, pager, next" @current-change="handleCurrentChange" @size-change="handleSizeChange" :page-sizes="[10,20, 50, 100, 500]" :current-page="pageInfo.pageNum" :page-size="pageInfo.pageSize" :total="pageInfo.total" style="float:right;" />
|
||||
</el-row>
|
||||
<el-row>
|
||||
<!--编辑 XmBudgetLabor 项目人力成本预算界面-->
|
||||
<mdp-dialog title="编辑项目人力预算" v-model="editFormVisible" width="60%" append-to-body :close-on-click-modal="false">
|
||||
<xm-budget-labor-edit op-type="edit" :xm-budget-labor="editForm" :visible="editFormVisible" @cancel="editFormVisible=false" @submit="afterEditSubmit" />
|
||||
</mdp-dialog>
|
||||
|
||||
<!--新增 XmBudgetLabor 项目人力成本预算界面-->
|
||||
<mdp-dialog title="新增项目人力预算" v-model="addFormVisible" width="60%" append-to-body :close-on-click-modal="false">
|
||||
<xm-budget-labor-add op-type="add" :sel-project="selProject" :visible="addFormVisible" @cancel="addFormVisible=false" @submit="afterAddSubmit" />
|
||||
</mdp-dialog>
|
||||
</el-row>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util';//全局公共库
|
||||
import config from '@/api/mdp_pub/mdp_config';//全局公共库
|
||||
import { listXmBudgetLabor, delXmBudgetLabor, batchDelXmBudgetLabor,editSomeFieldsXmBudgetLabor } from '@/api/xm/pro/xmBudgetLabor';
|
||||
import XmBudgetLaborEdit from './XmBudgetLaborEdit.vue';//新增修改界面
|
||||
import XmBudgetLaborAdd from './XmBudgetLaborAdd.vue';//新增修改界面
|
||||
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
export default {
|
||||
name:'xmBudgetLaborMng',
|
||||
components: {
|
||||
XmBudgetLaborEdit,XmBudgetLaborAdd
|
||||
},
|
||||
props:['visible',"selProject"],
|
||||
computed: {
|
||||
...mapState(useUserStore,['userInfo']),
|
||||
|
||||
},
|
||||
watch:{
|
||||
visible(val){
|
||||
if(val==true){
|
||||
this.initData();
|
||||
this.searchXmBudgetLabors()
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filters: {
|
||||
key: ''
|
||||
},
|
||||
xmBudgetLabors: [],//查询结果
|
||||
pageInfo:{//分页数据
|
||||
total:0,//服务器端收到0时,会自动计算总记录数,如果上传>0的不自动计算。
|
||||
pageSize:10,//每页数据
|
||||
count:true,//是否需要重新计算总记录数
|
||||
pageNum:1,//当前页码、从1开始计算
|
||||
orderFields:[],//排序列 如 ['sex','student_id'],必须为数据库字段
|
||||
orderDirs:[]//升序 asc,降序desc 如 性别 升序、学生编号降序 ['asc','desc']
|
||||
},
|
||||
load:{ list: false, edit: false, del: false, add: false },//查询中...
|
||||
sels: [],//列表选中数据
|
||||
dicts:{
|
||||
//sex: [{id:'1',name:'男'},{id:'2',name:'女'}]
|
||||
},//下拉选择框的所有静态数据 params={categoryId:'all',itemCodes:['sex']} 返回结果 {sex: [{id:'1',name:'男'},{id:'2',name:'女'}]}
|
||||
addFormVisible: false,//新增xmBudgetLabor界面是否显示
|
||||
addForm: {
|
||||
projectId:'',userid:'',budgetAt:'',id:'',remark:'',username:'',subjectId:'',bizSdate:'',bizEdate:'',bizMonth:'',instId:'',bizFlowState:'',costType:'',subjectName:'',branchId:'',ubranchId:''
|
||||
},
|
||||
|
||||
editFormVisible: false,//编辑界面是否显示
|
||||
editForm: {
|
||||
projectId:'',userid:'',budgetAt:'',id:'',remark:'',username:'',subjectId:'',bizSdate:'',bizEdate:'',bizMonth:'',instId:'',bizFlowState:'',costType:'',subjectName:'',branchId:'',ubranchId:''
|
||||
},
|
||||
maxTableHeight:300,
|
||||
}
|
||||
},//end data
|
||||
methods: {
|
||||
|
||||
...util,
|
||||
|
||||
handleSizeChange(pageSize) {
|
||||
this.pageInfo.pageSize=pageSize;
|
||||
this.getXmBudgetLabors();
|
||||
},
|
||||
handleCurrentChange(pageNum) {
|
||||
this.pageInfo.pageNum = pageNum;
|
||||
this.getXmBudgetLabors();
|
||||
},
|
||||
// 表格排序 obj.order=ascending/descending,需转化为 asc/desc ; obj.prop=表格中的排序字段,字段驼峰命名
|
||||
sortChange( obj ){
|
||||
if(obj.order==null){
|
||||
this.pageInfo.orderFields=[];
|
||||
this.pageInfo.orderDirs=[];
|
||||
}else{
|
||||
var dir='asc';
|
||||
if(obj.order=='ascending'){
|
||||
dir='asc'
|
||||
}else{
|
||||
dir='desc';
|
||||
}
|
||||
|
||||
this.pageInfo.orderFields=[util.toLine(obj.prop)];
|
||||
this.pageInfo.orderDirs=[dir];
|
||||
}
|
||||
this.getXmBudgetLabors();
|
||||
},
|
||||
searchXmBudgetLabors(){
|
||||
this.pageInfo.count=true;
|
||||
this.getXmBudgetLabors();
|
||||
},
|
||||
//获取列表 XmBudgetLabor 项目人力成本预算
|
||||
getXmBudgetLabors() {
|
||||
let params = {
|
||||
pageSize: this.pageInfo.pageSize,
|
||||
pageNum: this.pageInfo.pageNum,
|
||||
total: this.pageInfo.total,
|
||||
count:this.pageInfo.count
|
||||
};
|
||||
if(this.pageInfo.orderFields!=null && this.pageInfo.orderFields.length>0){
|
||||
let orderBys=[];
|
||||
for(var i=0;i<this.pageInfo.orderFields.length;i++){
|
||||
orderBys.push(this.pageInfo.orderFields[i]+" "+this.pageInfo.orderDirs[i])
|
||||
}
|
||||
params.orderBy= orderBys.join(",")
|
||||
}
|
||||
if(this.filters.key){
|
||||
params.key=this.filters.key
|
||||
}
|
||||
|
||||
this.load.list = true;
|
||||
listXmBudgetLabor(params).then((res) => {
|
||||
var tips=res.tips;
|
||||
if(tips.isOk){
|
||||
this.pageInfo.total = res.total;
|
||||
this.pageInfo.count=false;
|
||||
this.xmBudgetLabors = res.data;
|
||||
}else{
|
||||
this.$notify({ position:'bottom-left',showClose:true, message: tips.msg, type: 'error' });
|
||||
}
|
||||
this.load.list = false;
|
||||
}).catch( err => this.load.list = false );
|
||||
},
|
||||
|
||||
//显示编辑界面 XmBudgetLabor 项目人力成本预算
|
||||
showEdit: function ( row,index ) {
|
||||
this.editFormVisible = true;
|
||||
this.editForm = Object.assign({}, row);
|
||||
},
|
||||
//显示新增界面 XmBudgetLabor 项目人力成本预算
|
||||
showAdd: function () {
|
||||
this.addFormVisible = true;
|
||||
//this.addForm=Object.assign({}, this.editForm);
|
||||
},
|
||||
afterAddSubmit(){
|
||||
this.addFormVisible=false;
|
||||
this.pageInfo.count=true;
|
||||
this.getXmBudgetLabors();
|
||||
},
|
||||
afterEditSubmit(){
|
||||
this.editFormVisible=false;
|
||||
},
|
||||
//选择行xmBudgetLabor
|
||||
selsChange: function (sels) {
|
||||
this.sels = sels;
|
||||
},
|
||||
//删除xmBudgetLabor
|
||||
handleDel: function (row,index) {
|
||||
this.$confirm('确认删除该记录吗?', '提示', {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.load.del=true;
|
||||
let params = { id:row.id };
|
||||
delXmBudgetLabor(params).then((res) => {
|
||||
this.load.del=false;
|
||||
var tips=res.tips;
|
||||
if(tips.isOk){
|
||||
this.searchXmBudgetLabors();
|
||||
}
|
||||
this.$notify({ position:'bottom-left', showClose:true, message: tips.msg, type: tips.isOk?'success':'error' });
|
||||
}).catch( err => this.load.del=false );
|
||||
});
|
||||
},
|
||||
//批量删除xmBudgetLabor
|
||||
batchDel: function () {
|
||||
if(this.sels.length<=0){
|
||||
return;
|
||||
}
|
||||
var params=this.sels.map(i=>{
|
||||
return { id:i.id}
|
||||
})
|
||||
this.$confirm('确认删除选中记录吗?', '提示', {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.load.del=true;
|
||||
batchDelXmBudgetLabor(params).then((res) => {
|
||||
this.load.del=false;
|
||||
var tips=res.tips;
|
||||
if( tips.isOk ){
|
||||
this.searchXmBudgetLabors();
|
||||
}
|
||||
this.$notify({ position:'bottom-left',showClose:true, message: tips.msg, type: tips.isOk?'success':'error'});
|
||||
}).catch( err => this.load.del=false );
|
||||
});
|
||||
},
|
||||
editSomeFields(row,fieldName,$event){
|
||||
let params={};
|
||||
if(this.sels.length>0){
|
||||
if(!this.sels.some(k=> k.id==row.id)){
|
||||
this.$notify({position:'bottom-left',showClose:true,message:'请编辑选中的行',type:'warning'})
|
||||
Object.assign(this.editForm,this.editFormBak)
|
||||
return;
|
||||
}
|
||||
params['ids']=this.sels.map(i=>i.id)
|
||||
}else{
|
||||
params['ids']=[row].map(i=>i.id)
|
||||
}
|
||||
params[fieldName]=$event
|
||||
var func = editSomeFieldsXmBudgetLabor
|
||||
func(params).then(res=>{
|
||||
let tips = res.tips;
|
||||
if(tips.isOk){
|
||||
if(this.sels.length>0){
|
||||
this.searchXmBudgetLabors();
|
||||
}
|
||||
this.editFormBak=[...this.editForm]
|
||||
}else{
|
||||
Object.assign(this.editForm,this.editFormBak)
|
||||
this.$notify({position:'bottom-left',showClose:true,message:tips.msg,type:tips.isOk?'success':'error'})
|
||||
}
|
||||
}).catch((e)=>Object.assign(this.editForm,this.editFormBak))
|
||||
},
|
||||
rowClick: function(row, event, column){
|
||||
this.editForm=row
|
||||
this.editFormBak={...row};
|
||||
this.$emit('row-click',row, event, column);// @row-click="rowClick"
|
||||
},
|
||||
initData: function(){
|
||||
|
||||
},
|
||||
|
||||
},//end methods
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initData()
|
||||
this.searchXmBudgetLabors();
|
||||
//this.maxTableHeight =util.calcTableMaxHeight(this.$refs.xmBudgetLaborTable.$el)
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped />
|
||||
@@ -1,159 +0,0 @@
|
||||
<template>
|
||||
|
||||
<el-row class="page-header" />
|
||||
<el-row class="page-main" :style="{overflowX:'auto',height:maxTableHeight+'px'}" ref="table">
|
||||
<!--编辑界面 XmBudgetNlabor 项目人力成本预算-->
|
||||
<el-form :model="editForm" label-width="120px" :rules="editFormRules" ref="editFormRef">
|
||||
<el-form-item label="项目编号" prop="projectId">
|
||||
<el-input v-model="editForm.projectId" placeholder="项目编号" :maxlength="50" disabled/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预算金额/每月" prop="budgetAt">
|
||||
<el-input v-model="editForm.budgetAt" placeholder="预算金额/每月" :maxlength="10"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用途说明" prop="remark">
|
||||
<el-input v-model="editForm.remark" placeholder="备注" />
|
||||
</el-form-item>
|
||||
<el-form-item label="预算科目" prop="subjectId">
|
||||
<mdp-select item-code="projectSubject" placeholder="预算科目编号" v-model="editForm.subjectId"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预算月份" prop="bizMonth">
|
||||
<el-date-picker
|
||||
v-model="editForm.bizMonth"
|
||||
type="month"
|
||||
value-format="yyyy-MM"
|
||||
placeholder="选择年月">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<el-row class="page-bottom bottom-fixed">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button v-loading="load.edit" type="primary" @click="saveSubmit" :disabled="load.edit==true">提交</el-button>
|
||||
</el-row>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util';//全局公共库
|
||||
import config from "@/api/mdp_pub/mdp_config"; //全局公共库import
|
||||
import { addXmBudgetNlabor,editXmBudgetNlabor } from '@/api/xm/pro/xmBudgetNlabor';
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
export default {
|
||||
name:'xmBudgetNlaborEdit',
|
||||
components: {
|
||||
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore,[ 'userInfo' ]),
|
||||
|
||||
},
|
||||
props:['xmBudgetNlabor','visible','opType'],
|
||||
|
||||
watch: {
|
||||
'xmBudgetNlabor':function( xmBudgetNlabor ) {
|
||||
if(xmBudgetNlabor){
|
||||
this.editForm = {...xmBudgetNlabor};
|
||||
}
|
||||
|
||||
},
|
||||
'visible':function(visible) {
|
||||
if(visible==true){
|
||||
this.initData()
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currOpType:'add',//add/edit
|
||||
load:{ list: false, edit: false, del: false, add: false },//查询中...
|
||||
dicts:{
|
||||
projectSubject:[],
|
||||
},//下拉选择框的所有静态数据 params={categoryId:'all',itemCodes:['sex']} 返回结果 {sex: [{id:'1',name:'男'},{id:'2',name:'女'}]}
|
||||
editFormRules: {
|
||||
|
||||
subjectId: [
|
||||
{ required: true, message: '科目不能为空', trigger: 'change' }
|
||||
],
|
||||
username: [
|
||||
{ required: true, message: '姓名不能为空,如果不确定具体人,请填写岗位代替', trigger: 'change' }
|
||||
],
|
||||
budgetAt: [
|
||||
{ required: true, message: '金额不能为空', trigger: 'change' }
|
||||
],
|
||||
|
||||
remark: [
|
||||
{ required: true, message: '用途说明不能为空', trigger: 'change' }
|
||||
]
|
||||
},
|
||||
editForm: {
|
||||
id:'',projectId:'',budgetAt:'',remark:'',subjectId:'',bizSdate:'',bizEdate:'',instId:'',bizFlowState:'',costType:'',bizMonth:'',subjectName:'',branchId:''
|
||||
},
|
||||
maxTableHeight:300,
|
||||
}//end return
|
||||
},//end data
|
||||
methods: {
|
||||
|
||||
...util,
|
||||
|
||||
// 取消按钮点击 父组件监听@cancel="editFormVisible=false" 监听
|
||||
handleCancel:function(){
|
||||
this.$refs['editFormRef'].resetFields();
|
||||
this.$emit('cancel');
|
||||
},
|
||||
//新增、编辑提交XmBudgetNlabor 项目人力成本预算父组件监听@submit="afterEditSubmit"
|
||||
saveSubmit: function () {
|
||||
this.$refs.editFormRef.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$confirm('确认提交吗?', '提示', {}).then(() => {
|
||||
this.load.edit=true
|
||||
let params = Object.assign({}, this.editForm);
|
||||
var func=addXmBudgetNlabor
|
||||
if(this.currOpType=='edit'){
|
||||
func=editXmBudgetNlabor
|
||||
}
|
||||
func(params).then((res) => {
|
||||
this.load.edit=false
|
||||
var tips=res.tips;
|
||||
if(tips.isOk){
|
||||
this.editForm=res.data
|
||||
this.initData()
|
||||
this.currOpType="edit";
|
||||
this.$emit('submit');// @submit="afterAddSubmit"
|
||||
}
|
||||
this.$notify({ position:'bottom-left',showClose:true, message: tips.msg, type: tips.isOk?'success':'error' });
|
||||
}).catch( err =>this.load.edit=false);
|
||||
});
|
||||
}else{
|
||||
this.$notify({ showClose:true, message: "表单验证不通过,请修改表单数据再提交", type: 'error' });
|
||||
}
|
||||
});
|
||||
},
|
||||
initData: function(){
|
||||
this.currOpType=this.opType
|
||||
if(this.xmBudgetNlabor){
|
||||
this.editForm = Object.assign({},this.xmBudgetNlabor);
|
||||
}
|
||||
|
||||
if(this.opType=='edit'){
|
||||
|
||||
}else{
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
},//end method
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
|
||||
this.initData()
|
||||
//this.maxTableHeight =util.calcTableMaxHeight(this.$refs.table.$el)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped />
|
||||
@@ -1,338 +0,0 @@
|
||||
<template>
|
||||
|
||||
<el-row>
|
||||
<el-input v-model="filters.key" style="width: 20%;" placeholder="模糊查询"/>
|
||||
<el-button v-loading="load.list" :disabled="load.list==true" @click="searchXmBudgetNlabors" icon="search">查询</el-button>
|
||||
<span style="float:right;">
|
||||
<el-button type="primary" @click="showAdd" icon="plus" plain/>
|
||||
<el-button type="danger" v-loading="load.del" @click="batchDel" :disabled="this.sels.length===0 || load.del==true" icon="delete" plain/>
|
||||
</span>
|
||||
</el-row>
|
||||
<el-row class="padding-top">
|
||||
<!--列表 XmBudgetNlabor 项目人力成本预算-->
|
||||
<el-table ref="xmBudgetNlaborTable" :data="xmBudgetNlabors" v-adaptive="{bottom:50}" @sort-change="sortChange" highlight-current-row v-loading="load.list" border @selection-change="selsChange" @row-click="rowClick" style="width: 100%;">
|
||||
<el-table-column type="selection" width="55" show-overflow-tooltip fixed="left" />
|
||||
<el-table-column sortable type="index" width="55" show-overflow-tooltip fixed="left" />
|
||||
<!--
|
||||
<el-table-column sortable prop="username" width="55" show-overflow-tooltip fixed="left">
|
||||
<span class="cell-text"> {{scope.row.username}}} </span>
|
||||
<span class="cell-bar"><el-input style="display:inline;" v-model="scope.row.username" placeholder="" @change="editSomeFields(scope.row,'username',$event)" :maxlength="22"/></span>
|
||||
</el-table-column>
|
||||
-->
|
||||
<el-table-column prop="projectId" label="项目编号" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="cell-text"> {{scope.row.projectId}} </span>
|
||||
<span class="cell-bar"><el-input style="display:inline;" v-model="scope.row.username" placeholder="" @change="editSomeFields(scope.row,'username',$event)" :maxlength="22"/></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="用途说明" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="cell-text"> {{scope.row.remark}} </span>
|
||||
<span class="cell-bar"><el-input style="display:inline;" v-model="scope.row.remark" placeholder="" @change="editSomeFields(scope.row,'remark',$event)" :maxlength="22"/></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="budgetAt" label="预算金额" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="cell-text"> {{scope.row.budgetAt}} </span>
|
||||
<span class="cell-bar"><el-input type="number" style="display:inline;" v-model="scope.row.budgetAt" placeholder="" @change="editSomeFields(scope.row,'budgetAt',$event)" :maxlength="22"/></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="subjectId" label="预算科目" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<div class="cell-text">
|
||||
{{formatDicts(dicts,'projectSubject',scope.row.subjectId)}}
|
||||
</div>
|
||||
<span class="cell-bar">
|
||||
<el-select v-model="scope.row.subjectId" placeholder="预算科目" style="display:block;" @change="editSomeFields(scope.row,'subjectId',$event)">
|
||||
<el-option :value="item.id" :label="item.name" v-for="(item,index) in dicts.projectSubject" :key="index"/>
|
||||
</el-select>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bizMonth" label="费用月份" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="cell-text"> {{scope.row.bizMonth}} </span>
|
||||
<span class="cell-bar">
|
||||
<el-date-picker
|
||||
@change="editSomeFields(scope.row,'bizMonth',$event)"
|
||||
v-model="scope.row.bizMonth"
|
||||
type="month"
|
||||
value-format="yyyy-MM"
|
||||
placeholder="选择年月" />
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" @click="showEdit( scope.row,scope.$index)" icon="edit" plain/>
|
||||
<el-button type="danger" @click="handleDel(scope.row,scope.$index)" icon="delete" plain/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination layout="total, sizes, prev, pager, next" @current-change="handleCurrentChange" @size-change="handleSizeChange" :page-sizes="[10,20, 50, 100, 500]" :current-page="pageInfo.pageNum" :page-size="pageInfo.pageSize" :total="pageInfo.total" style="float:right;" />
|
||||
</el-row>
|
||||
<el-row>
|
||||
<!--编辑 XmBudgetNlabor 项目人力成本预算界面-->
|
||||
<mdp-dialog title="编辑项目非人力预算" v-model="editFormVisible" width="60%" append-to-body :close-on-click-modal="false">
|
||||
<xm-budget-nlabor-edit op-type="edit" :xm-budget-nlabor="editForm" :visible="editFormVisible" @cancel="editFormVisible=false" @submit="afterEditSubmit" />
|
||||
</mdp-dialog>
|
||||
|
||||
<!--新增 XmBudgetNlabor 项目人力成本预算界面-->
|
||||
<mdp-dialog title="新增项目非人力预算" v-model="addFormVisible" width="60%" append-to-body :close-on-click-modal="false">
|
||||
<xm-budget-nlabor-add op-type="add" :sel-project="selProject" :visible="addFormVisible" @cancel="addFormVisible=false" @submit="afterAddSubmit" />
|
||||
</mdp-dialog>
|
||||
</el-row>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util';//全局公共库
|
||||
import config from '@/api/mdp_pub/mdp_config';//全局公共库
|
||||
import { listXmBudgetNlabor, delXmBudgetNlabor, batchDelXmBudgetNlabor,editSomeFieldsXmBudgetNlabor } from '@/api/xm/pro/xmBudgetNlabor';
|
||||
import XmBudgetNlaborEdit from './XmBudgetNlaborEdit.vue';//新增修改界面
|
||||
import XmBudgetNlaborAdd from './XmBudgetNlaborAdd.vue';//新增修改界面
|
||||
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
export default {
|
||||
name:'xmBudgetNlaborMng',
|
||||
components: {
|
||||
XmBudgetNlaborEdit,XmBudgetNlaborAdd
|
||||
},
|
||||
props:["selProject",'xmBudgetNlabor','fieldName','queryType','visible'],
|
||||
computed: {
|
||||
...mapState(useUserStore,['userInfo']),
|
||||
|
||||
},
|
||||
watch:{
|
||||
visible(val){
|
||||
if(val==true){
|
||||
this.initData();
|
||||
this.searchXmBudgetNlabors()
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filters: {
|
||||
key: ''
|
||||
},
|
||||
xmBudgetNlabors: [],//查询结果
|
||||
pageInfo:{//分页数据
|
||||
total:0,//服务器端收到0时,会自动计算总记录数,如果上传>0的不自动计算。
|
||||
pageSize:10,//每页数据
|
||||
count:true,//是否需要重新计算总记录数
|
||||
pageNum:1,//当前页码、从1开始计算
|
||||
orderFields:[],//排序列 如 ['sex','student_id'],必须为数据库字段
|
||||
orderDirs:[]//升序 asc,降序desc 如 性别 升序、学生编号降序 ['asc','desc']
|
||||
},
|
||||
load:{ list: false, edit: false, del: false, add: false },//查询中...
|
||||
sels: [],//列表选中数据
|
||||
dicts:{
|
||||
//sex: [{id:'1',name:'男'},{id:'2',name:'女'}]
|
||||
},//下拉选择框的所有静态数据 params={categoryId:'all',itemCodes:['sex']} 返回结果 {sex: [{id:'1',name:'男'},{id:'2',name:'女'}]}
|
||||
addFormVisible: false,//新增xmBudgetNlabor界面是否显示
|
||||
addForm: {
|
||||
id:'',projectId:'',budgetAt:'',remark:'',subjectId:'',bizSdate:'',bizEdate:'',instId:'',bizFlowState:'',costType:'',bizMonth:'',subjectName:'',branchId:''
|
||||
},
|
||||
|
||||
editFormVisible: false,//编辑界面是否显示
|
||||
editForm: {
|
||||
id:'',projectId:'',budgetAt:'',remark:'',subjectId:'',bizSdate:'',bizEdate:'',instId:'',bizFlowState:'',costType:'',bizMonth:'',subjectName:'',branchId:''
|
||||
},
|
||||
maxTableHeight:300,
|
||||
}
|
||||
},//end data
|
||||
methods: {
|
||||
|
||||
...util,
|
||||
|
||||
handleSizeChange(pageSize) {
|
||||
this.pageInfo.pageSize=pageSize;
|
||||
this.getXmBudgetNlabors();
|
||||
},
|
||||
handleCurrentChange(pageNum) {
|
||||
this.pageInfo.pageNum = pageNum;
|
||||
this.getXmBudgetNlabors();
|
||||
},
|
||||
// 表格排序 obj.order=ascending/descending,需转化为 asc/desc ; obj.prop=表格中的排序字段,字段驼峰命名
|
||||
sortChange( obj ){
|
||||
if(obj.order==null){
|
||||
this.pageInfo.orderFields=[];
|
||||
this.pageInfo.orderDirs=[];
|
||||
}else{
|
||||
var dir='asc';
|
||||
if(obj.order=='ascending'){
|
||||
dir='asc'
|
||||
}else{
|
||||
dir='desc';
|
||||
}
|
||||
|
||||
this.pageInfo.orderFields=[util.toLine(obj.prop)];
|
||||
this.pageInfo.orderDirs=[dir];
|
||||
}
|
||||
this.getXmBudgetNlabors();
|
||||
},
|
||||
searchXmBudgetNlabors(){
|
||||
this.pageInfo.count=true;
|
||||
this.getXmBudgetNlabors();
|
||||
},
|
||||
//获取列表 XmBudgetNlabor 项目人力成本预算
|
||||
getXmBudgetNlabors() {
|
||||
let params = {
|
||||
pageSize: this.pageInfo.pageSize,
|
||||
pageNum: this.pageInfo.pageNum,
|
||||
total: this.pageInfo.total,
|
||||
count:this.pageInfo.count
|
||||
};
|
||||
if(this.pageInfo.orderFields!=null && this.pageInfo.orderFields.length>0){
|
||||
let orderBys=[];
|
||||
for(var i=0;i<this.pageInfo.orderFields.length;i++){
|
||||
orderBys.push(this.pageInfo.orderFields[i]+" "+this.pageInfo.orderDirs[i])
|
||||
}
|
||||
params.orderBy= orderBys.join(",")
|
||||
}
|
||||
if(this.filters.key){
|
||||
params.key=this.filters.key
|
||||
}
|
||||
if(this.queryType=='queryByBizMonth'){
|
||||
params.bizMonth=this.fieldName
|
||||
params.username=this.budgetCostNouser.username
|
||||
params.subjectId=this.budgetCostNouser.subjectId
|
||||
}else if(this.queryType=='queryByUsername'){
|
||||
params.username=this.budgetCostNouser.username
|
||||
params.subjectId=this.budgetCostNouser.subjectId
|
||||
}else if(this.queryType=='queryBySubjectId'){
|
||||
params.subjectId=this.budgetCostNouser.subjectId
|
||||
}
|
||||
if(this.selProject!=null && this.selProject !=undefined){
|
||||
params.projectId=this.selProject.id
|
||||
}
|
||||
|
||||
this.load.list = true;
|
||||
listXmBudgetNlabor(params).then((res) => {
|
||||
var tips=res.tips;
|
||||
if(tips.isOk){
|
||||
this.pageInfo.total = res.total;
|
||||
this.pageInfo.count=false;
|
||||
this.xmBudgetNlabors = res.data;
|
||||
}else{
|
||||
this.$notify({ position:'bottom-left',showClose:true, message: tips.msg, type: 'error' });
|
||||
}
|
||||
this.load.list = false;
|
||||
}).catch( err => this.load.list = false );
|
||||
},
|
||||
|
||||
//显示编辑界面 XmBudgetNlabor 项目人力成本预算
|
||||
showEdit: function ( row,index ) {
|
||||
this.editFormVisible = true;
|
||||
this.editForm = Object.assign({}, row);
|
||||
},
|
||||
//显示新增界面 XmBudgetNlabor 项目人力成本预算
|
||||
showAdd: function () {
|
||||
this.addFormVisible = true;
|
||||
//this.addForm=Object.assign({}, this.editForm);
|
||||
},
|
||||
afterAddSubmit(){
|
||||
this.addFormVisible=false;
|
||||
this.pageInfo.count=true;
|
||||
this.getXmBudgetNlabors();
|
||||
},
|
||||
afterEditSubmit(){
|
||||
this.editFormVisible=false;
|
||||
},
|
||||
//选择行xmBudgetNlabor
|
||||
selsChange: function (sels) {
|
||||
this.sels = sels;
|
||||
},
|
||||
//删除xmBudgetNlabor
|
||||
handleDel: function (row,index) {
|
||||
this.$confirm('确认删除该记录吗?', '提示', {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.load.del=true;
|
||||
let params = { id:row.id };
|
||||
delXmBudgetNlabor(params).then((res) => {
|
||||
this.load.del=false;
|
||||
var tips=res.tips;
|
||||
if(tips.isOk){
|
||||
this.searchXmBudgetNlabors();
|
||||
}
|
||||
this.$notify({ position:'bottom-left', showClose:true, message: tips.msg, type: tips.isOk?'success':'error' });
|
||||
}).catch( err => this.load.del=false );
|
||||
});
|
||||
},
|
||||
//批量删除xmBudgetNlabor
|
||||
batchDel: function () {
|
||||
if(this.sels.length<=0){
|
||||
return;
|
||||
}
|
||||
var params=this.sels.map(i=>{
|
||||
return { id:i.id}
|
||||
})
|
||||
this.$confirm('确认删除选中记录吗?', '提示', {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.load.del=true;
|
||||
batchDelXmBudgetNlabor(params).then((res) => {
|
||||
this.load.del=false;
|
||||
var tips=res.tips;
|
||||
if( tips.isOk ){
|
||||
this.searchXmBudgetNlabors();
|
||||
}
|
||||
this.$notify({ position:'bottom-left',showClose:true, message: tips.msg, type: tips.isOk?'success':'error'});
|
||||
}).catch( err => this.load.del=false );
|
||||
});
|
||||
},
|
||||
editSomeFields(row,fieldName,$event){
|
||||
let params={};
|
||||
if(this.sels.length>0){
|
||||
if(!this.sels.some(k=> k.id==row.id)){
|
||||
this.$notify({position:'bottom-left',showClose:true,message:'请编辑选中的行',type:'warning'})
|
||||
Object.assign(this.editForm,this.editFormBak)
|
||||
return;
|
||||
}
|
||||
params['ids']=this.sels.map(i=>i.id)
|
||||
}else{
|
||||
params['ids']=[row].map(i=>i.id)
|
||||
}
|
||||
params[fieldName]=$event
|
||||
var func = editSomeFieldsXmBudgetNlabor
|
||||
func(params).then(res=>{
|
||||
let tips = res.tips;
|
||||
if(tips.isOk){
|
||||
if(this.sels.length>0){
|
||||
this.searchXmBudgetNlabors();
|
||||
}
|
||||
this.editFormBak=[...this.editForm]
|
||||
}else{
|
||||
Object.assign(this.editForm,this.editFormBak)
|
||||
this.$notify({position:'bottom-left',showClose:true,message:tips.msg,type:tips.isOk?'success':'error'})
|
||||
}
|
||||
}).catch((e)=>Object.assign(this.editForm,this.editFormBak))
|
||||
},
|
||||
rowClick: function(row, event, column){
|
||||
this.editForm=row
|
||||
this.editFormBak={...row};
|
||||
this.$emit('row-click',row, event, column);// @row-click="rowClick"
|
||||
},
|
||||
initData: function(){
|
||||
|
||||
},
|
||||
|
||||
},//end methods
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
|
||||
this.initData()
|
||||
this.searchXmBudgetNlabors();
|
||||
//this.maxTableHeight =util.calcTableMaxHeight(this.$refs.xmBudgetNlaborTable.$el)
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped />
|
||||
@@ -1,40 +1,54 @@
|
||||
<template>
|
||||
|
||||
<el-row class="page-header" />
|
||||
<el-row class="page-main" :style="{overflowX:'auto',height:maxTableHeight+'px'}" ref="table">
|
||||
<!--编辑界面 XmBudgetLabor 项目人力成本预算-->
|
||||
<!--编辑界面 XmBudgetRecord 项目人力成本预算-->
|
||||
<el-form :model="editForm" label-width="120px" :rules="editFormRules" ref="editFormRef">
|
||||
<el-form-item label="预算总金额" prop="totalBudgetAt">
|
||||
¥<el-input type="number" style="width:40%;" v-model="totalBudgetAt" placeholder="预算金额"/> 元
|
||||
平均 ¥{{editForm.budgetAt}} 元 / 月
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名称" prop="username">
|
||||
<el-input v-model="editForm.username" placeholder="用户,如果不确定具体人员,可用岗位代替" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用途说明" prop="remark">
|
||||
<el-input v-model="editForm.remark" placeholder="备注" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="成本中心" prop="costCenterId">
|
||||
<MdpSelectDept width="100%" v-model="editForm.costCenterId" placeholder="成本中心" title="成本中心"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预算科目" prop="subjectId">
|
||||
<mdp-select item-code="projectSubject" placeholder="预算科目编号" v-model="editForm.subjectId"/>
|
||||
<mdp-select width="100%" item-code="projectSubject" placeholder="预算科目编号" v-model="editForm.subjectId"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预算总金额">
|
||||
<el-input type="number" v-model="totalBudgetAt" placeholder="预算总金额">
|
||||
<template #suffix>元,{{ parseInt(totalBudgetAt/10000) }}万元</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="分摊月份" prop="bizMonth">
|
||||
<el-space wrap fill>
|
||||
<el-date-picker
|
||||
v-model="bizYear"
|
||||
type="year"
|
||||
value-format="yyyy"
|
||||
value-format="YYYY"
|
||||
placeholder="选择年" />
|
||||
<div style="margin-top: 20px">
|
||||
<el-checkbox-group v-model="bizMonths" size="medium">
|
||||
<div>
|
||||
<el-checkbox-group v-model="bizMonths" >
|
||||
<el-checkbox-button v-for="i in bizMonthList" :label="i" :key="i">{{i}}</el-checkbox-button>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
<div style="padding-top:20px;">下一年:{{secBizYear}}</div>
|
||||
<div style="margin-top: 20px">
|
||||
<el-checkbox-group v-model="secBizMonths" size="medium">
|
||||
</div>
|
||||
<div>下一年:{{secBizYear}}</div>
|
||||
<div>
|
||||
<el-checkbox-group v-model="secBizMonths" >
|
||||
<el-checkbox-button v-for="i in bizMonthList" :label="i" :key="i">{{i}}</el-checkbox-button>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-space>
|
||||
</el-form-item>
|
||||
<el-form-item label="预算金额" prop="budgetAt">
|
||||
<div>{{ editForm.budgetAt||0 }} <el-text type="primary">元/每月</el-text>
|
||||
</div>
|
||||
<div>
|
||||
<el-text type="info"> {{ parseInt((editForm.budgetAt||0)/10000) }} 万元/每月</el-text>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="费用主责" prop="userid">
|
||||
<MdpSelectUser width="100%" v-model="editForm.userid" :init-name="editForm.username" @change2="($event)=>editForm.username=$event?.username" />
|
||||
<el-text type="primary">如果无法确定具体人员,请在备注说明,方便后续修正</el-text>
|
||||
</el-form-item>
|
||||
<el-form-item label="用途说明" prop="remark">
|
||||
<el-input type="textarea" v-model="editForm.remark" placeholder="备注" />
|
||||
</el-form-item>
|
||||
<!--
|
||||
<el-form-item label="成本类型" prop="costType">
|
||||
<template>
|
||||
@@ -45,24 +59,25 @@
|
||||
</el-form-item>
|
||||
-->
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<el-row class="page-bottom bottom-fixed">
|
||||
<div class="footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button v-loading="load.edit" type="primary" @click="saveSubmit" :disabled="load.edit==true">提交</el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util';//全局公共库
|
||||
import config from "@/api/mdp_pub/mdp_config"; //全局公共库import
|
||||
import { addXmBudgetLabor,editXmBudgetLabor,batchAddXmBudgetLabor } from '@/api/xm/pro/xmBudgetLabor';
|
||||
import { batchAddXmBudgetRecord,editXmBudgetRecord } from '@/api/xm/pro/xmBudgetRecord';
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
export default {
|
||||
name:'xmBudgetLaborEdit',
|
||||
import {MdpFormMixin} from "@/components/mdp-ui/mixin/MdpFormMixin.js"
|
||||
export default {
|
||||
mixins:[MdpFormMixin],
|
||||
name:'XmBudgetRecordAdd',
|
||||
components: {
|
||||
|
||||
},
|
||||
@@ -81,17 +96,17 @@ import { useUserStore } from '@/store/modules/user'
|
||||
if(!this.totalBudgetAt){
|
||||
return 0;
|
||||
}
|
||||
return Math.round(parseFloat(this.totalBudgetAt)/this.allMonths.length);
|
||||
return parseFloat(this.totalBudgetAt)/this.allMonths.length;
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
props:['xmBudgetLabor','visible','opType','selProject'],
|
||||
props:['formData','visible','subOpType','selProject'],
|
||||
|
||||
watch: {
|
||||
'xmBudgetLabor':function( xmBudgetLabor ) {
|
||||
if(xmBudgetLabor){
|
||||
this.editForm = {...xmBudgetLabor};
|
||||
'formData':function( formData ) {
|
||||
if(formData){
|
||||
this.editForm = {...formData};
|
||||
}
|
||||
|
||||
},
|
||||
@@ -113,10 +128,7 @@ import { useUserStore } from '@/store/modules/user'
|
||||
var secYear=parseInt(year)+1;
|
||||
return {
|
||||
currOpType:'add',//add/edit
|
||||
load:{ list: false, edit: false, del: false, add: false },//查询中...
|
||||
dicts:{
|
||||
projectSubject:[],
|
||||
},//下拉选择框的所有静态数据 params={categoryId:'all',itemCodes:['sex']} 返回结果 {sex: [{id:'1',name:'男'},{id:'2',name:'女'}]}
|
||||
|
||||
editFormRules: {
|
||||
subjectId: [
|
||||
{ required: true, message: '科目不能为空', trigger: 'change' }
|
||||
@@ -128,14 +140,13 @@ import { useUserStore } from '@/store/modules/user'
|
||||
{ required: true, message: '金额不能为空', trigger: 'change' }
|
||||
],
|
||||
|
||||
remark: [
|
||||
{ required: true, message: '用途说明不能为空', trigger: 'change' }
|
||||
]
|
||||
// remark: [
|
||||
// { required: true, message: '用途说明不能为空', trigger: 'change' }
|
||||
// ]
|
||||
},
|
||||
editForm: {
|
||||
projectId:'',userid:'',budgetAt:'',id:'',remark:'',username:'',subjectId:'',bizSdate:'',bizEdate:'',bizMonth:'',instId:'',bizFlowState:'',costType:'',subjectName:'',branchId:'',ubranchId:''
|
||||
},
|
||||
maxTableHeight:300,
|
||||
|
||||
totalBudgetAt:0,
|
||||
bizYear:year+'',
|
||||
@@ -145,22 +156,18 @@ import { useUserStore } from '@/store/modules/user'
|
||||
bizMonthList:['01','02','03','04','05','06','07','08','09','10','11','12'],
|
||||
}//end return
|
||||
},//end data
|
||||
methods: {
|
||||
|
||||
...util,
|
||||
|
||||
// 取消按钮点击 父组件监听@cancel="editFormVisible=false" 监听
|
||||
handleCancel:function(){
|
||||
this.$refs['editFormRef'].resetFields();
|
||||
this.$emit('cancel');
|
||||
},
|
||||
//新增、编辑提交XmBudgetLabor 项目人力成本预算父组件监听@submit="afterEditSubmit"
|
||||
methods: {
|
||||
//新增、编辑提交XmBudgetRecord 项目人力成本预算父组件监听@submit="afterEditSubmit"
|
||||
saveSubmit: function () {
|
||||
if(this.bizYear==null || this.bizYear==''){
|
||||
this.$notify({position:'bottom-left',showClose:true,message:"请选择需要分摊的年份", type: 'error' });
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.allMonths.length<=0){
|
||||
this.$notify({position:'bottom-left',showClose:true,message:"请选择需要分摊的月份", type: 'error' });
|
||||
return;
|
||||
}
|
||||
var list=this.allMonths.map(i=>{
|
||||
let params = Object.assign({}, this.editForm);
|
||||
params.projectId=this.selProject.id
|
||||
@@ -173,14 +180,11 @@ import { useUserStore } from '@/store/modules/user'
|
||||
if (valid) {
|
||||
this.$confirm('确认提交吗?', '提示', {}).then(() => {
|
||||
this.load.edit=true
|
||||
var func=batchAddXmBudgetLabor
|
||||
var func=batchAddXmBudgetRecord
|
||||
func(list).then((res) => {
|
||||
this.load.edit=false
|
||||
var tips=res.tips;
|
||||
if(tips.isOk){
|
||||
this.editForm=res.data
|
||||
this.initData()
|
||||
this.currOpType="edit";
|
||||
this.$emit('submit');// @submit="afterAddSubmit"
|
||||
}
|
||||
this.$notify({ position:'bottom-left',showClose:true, message: tips.msg, type: tips.isOk?'success':'error' });
|
||||
@@ -191,25 +195,11 @@ import { useUserStore } from '@/store/modules/user'
|
||||
}
|
||||
});
|
||||
},
|
||||
initData: function(){
|
||||
this.currOpType=this.opType
|
||||
if(this.xmBudgetLabor){
|
||||
this.editForm = Object.assign({},this.xmBudgetLabor);
|
||||
}
|
||||
|
||||
if(this.opType=='edit'){
|
||||
|
||||
}else{
|
||||
|
||||
}
|
||||
},
|
||||
initCurrData: function(){
|
||||
}
|
||||
|
||||
},//end method
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initData()
|
||||
//this.maxTableHeight =util.calcTableMaxHeight(this.$refs.table.$el)
|
||||
});
|
||||
mounted() {
|
||||
}
|
||||
}
|
||||
|
||||
105
src/views/xm/pro/xmBudgetRecord/EditForm.vue
Normal file
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
|
||||
<!--编辑界面 XmBudgetRecord 项目人力成本预算-->
|
||||
<el-form :model="editForm" label-width="120px" :rules="editFormRules" ref="editFormRef">
|
||||
|
||||
<el-form-item label="成本中心" prop="costCenterId">
|
||||
<MdpSelectDept width="100%" v-model="editForm.costCenterId" placeholder="成本中心" title="成本中心"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="项目编号" prop="projectId">
|
||||
<el-input v-model="editForm.projectId" placeholder="项目编号" :maxlength="50" disabled/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="预算科目" prop="subjectId">
|
||||
<mdp-select width="100%" item-code="projectSubject" placeholder="预算科目编号" v-model="editForm.subjectId"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预算金额" prop="budgetAt">
|
||||
<el-input v-model="editForm.budgetAt" placeholder="预算金额/每月" type="number">
|
||||
<template #suffix>元/每月</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="费用主责" prop="userid">
|
||||
<MdpSelectUser width="100%" v-model="editForm.userid" :init-name="editForm.username" @change2="($event)=>editForm.username=$event?.username" />
|
||||
<el-text type="primary">如果无法确定具体人员,请在备注说明,方便后续修正</el-text>
|
||||
</el-form-item>
|
||||
<el-form-item label="用途说明" prop="remark">
|
||||
<el-input type="textarea" v-model="editForm.remark" placeholder="备注" />
|
||||
</el-form-item>
|
||||
<el-form-item label="预算月份" prop="bizMonth">
|
||||
<el-date-picker
|
||||
v-model="editForm.bizMonth"
|
||||
type="month"
|
||||
value-format="YYYY-MM"
|
||||
placeholder="选择年月"/>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
|
||||
<el-row class="footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button v-loading="load.edit" type="primary" @click="saveSubmit" :disabled="load.edit==true">提交</el-button>
|
||||
</el-row>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util';//全局公共库
|
||||
import config from "@/api/mdp_pub/mdp_config"; //全局公共库import
|
||||
import { addXmBudgetRecord,editXmBudgetRecord } from '@/api/xm/pro/xmBudgetRecord';
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
import {MdpFormMixin} from "@/components/mdp-ui/mixin/MdpFormMixin.js"
|
||||
export default {
|
||||
mixins:[MdpFormMixin],
|
||||
name:'xmBudgetRecordEdit',
|
||||
components: {
|
||||
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore,[ 'userInfo' ]),
|
||||
|
||||
},
|
||||
props:['formData','visible','subOpType'],
|
||||
|
||||
watch: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currOpType:'add',//add/edit
|
||||
load:{ list: false, edit: false, del: false, add: false },//查询中...
|
||||
|
||||
editFormRules: {
|
||||
subjectId: [
|
||||
{ required: true, message: '科目不能为空', trigger: 'change' }
|
||||
],
|
||||
username: [
|
||||
{ required: true, message: '姓名不能为空,如果不确定具体人,请填写岗位代替', trigger: 'change' }
|
||||
],
|
||||
budgetAt: [
|
||||
{ required: true, message: '金额不能为空', trigger: 'change' }
|
||||
],
|
||||
|
||||
// remark: [
|
||||
// { required: true, message: '用途说明不能为空', trigger: 'change' }
|
||||
// ]
|
||||
},
|
||||
editForm: {
|
||||
projectId:'',userid:'',budgetAt:'',id:'',remark:'',username:'',subjectId:'',bizSdate:'',bizEdate:'',bizMonth:'',instId:'',bizFlowState:'',costType:'',subjectName:'',branchId:'',ubranchId:''
|
||||
},
|
||||
apis:{
|
||||
edit: editXmBudgetRecord,
|
||||
}
|
||||
}//end return
|
||||
},//end data
|
||||
methods: {
|
||||
initCurrData: function(){
|
||||
|
||||
},
|
||||
|
||||
},//end method
|
||||
mounted() {
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
194
src/views/xm/pro/xmBudgetRecord/Index.vue
Normal file
@@ -0,0 +1,194 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<template #header>
|
||||
<el-space>
|
||||
<MdpSelectDept v-model="filters.costCenterId" placeholder="成本中心" title="成本中心"/>
|
||||
<mdp-hi-query ref="hiQueryBtn" :column-configs="columnConfigs" v-model="hiQueryParams"
|
||||
@change="onHiQueryParamsChange" />
|
||||
<el-button icon="zoom-out" @click="searchReset()" title="重置查询条件并查询" ref="searchResetBtn" />
|
||||
<el-button icon="download" @click="export2Excel()" title="导出当前结果数据" plain ref="downloadBtn" />
|
||||
<mdp-table-configs :column-configs="columnConfigs" v-model="checkedColumns" ref="columnConfigsBtn" />
|
||||
<el-button type="primary" @click="showAdd" icon="plus" plain />
|
||||
<el-button type="danger" v-loading="load.del" @click="batchDel" :disabled="this.sels.length === 0 || load.del == true"
|
||||
icon="delete" plain />
|
||||
</el-space>
|
||||
</template>
|
||||
<el-space>
|
||||
<XmProjectSelect v-model="filters.projectId" @change2="project = $event" v-if="!selProject?.id" />
|
||||
<mdp-select item-code="projectSubject" v-model="filters.subjectId" placeholder="科目" />
|
||||
<mdp-date-range start-key="startBizMonth" end-key="endBizMonth" type="monthrange" v-model="filters" value-format="YYYY-MM" format="YYYY-MM" placeholder="统计时间" :clearable="false" />
|
||||
<MdpSelect itemCode="bizFlowState" v-model="filters.bizFlowState" placeholder="审核状态"/>
|
||||
|
||||
<el-input v-model="filters.name" placeholder="姓名" />
|
||||
<el-input v-model="filters.name" placeholder="用途" />
|
||||
<el-button v-loading="load.list" :disabled="load.list == true" @click="searchTableDatas" icon="search">查询</el-button>
|
||||
|
||||
</el-space>
|
||||
</ContentWrap>
|
||||
<!--列表 XmBudgetRecord 项目成本预算-->
|
||||
<el-table ref="table" :data="tableDatas" v-adaptive="{ bottom: 50 }" @sort-change="sortChange" highlight-current-row
|
||||
v-loading="load.list" border @selection-change="selsChange" @row-click="rowClick" style="width: 100%;">
|
||||
<el-table-column type="selection" width="55" show-overflow-tooltip fixed="left" />
|
||||
<el-table-column sortable type="index" width="55" show-overflow-tooltip fixed="left" />
|
||||
<!--
|
||||
<el-table-column sortable prop="username" width="55" show-overflow-tooltip fixed="left">
|
||||
<span class="cell-text"> {{scope.row.username}}} </span>
|
||||
<span class="cell-bar"><el-input style="display:inline;" v-model="scope.row.username" placeholder="" @change="editSomeFields(scope.row,'username',$event)" :maxlength="22"/></span>
|
||||
</el-table-column>
|
||||
-->
|
||||
<el-table-column prop="projectId" label="项目编号" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span> {{ scope.row.projectId }} </span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bizFlowState" label="审核状态" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<MdpSelect itemCode="bizFlowState" v-model="scope.row.bizFlowState" showStyle="tag" @change="editSomeFields(scope.row, 'bizFlowState', $event)"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="username" label="主责" min-width="80" show-overflow-tooltip/>
|
||||
<el-table-column prop="subjectId" label="预算科目" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<mdp-select item-code="projectSubject" show-style="tag" v-model="scope.row.subjectId" placeholder="预算科目" @change="editSomeFields(scope.row, 'subjectId', $event)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="用途说明" min-width="80" show-overflow-tooltip/>
|
||||
<el-table-column prop="budgetAt" label="预算金额" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
¥{{$mdp.toFixed(scope.row.budgetAt,2)}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bizMonth" label="费用月份" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="cell-text"> {{ scope.row.bizMonth }} </span>
|
||||
<span class="cell-bar">
|
||||
<el-date-picker @change="editSomeFields(scope.row, 'bizMonth', $event)" v-model="scope.row.bizMonth" type="month"
|
||||
value-format="YYYY-MM" placeholder="选择年月" />
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="warning" @click="showSplit(scope.row, scope.$index)" icon="operation" plain title="费用拆分"/>
|
||||
<el-button type="primary" @click="showEdit(scope.row, scope.$index)" icon="edit" plain />
|
||||
<el-button type="danger" @click="handleDel(scope.row, scope.$index)" icon="delete" plain />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination layout="total, sizes, prev, pager, next" @current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100, 500]" :current-page="pageInfo.pageNum"
|
||||
:page-size="pageInfo.pageSize" :total="pageInfo.total" style="float:right;" />
|
||||
|
||||
<!--编辑 XmBudgetRecord 项目成本预算界面-->
|
||||
<mdp-dialog title="编辑项目预算" v-model="editFormVisible" width="60%" append-to-body :close-on-click-modal="false">
|
||||
<XmBudgetRecordEdit sub-op-type="edit" :formData="editForm" :visible="editFormVisible"
|
||||
@cancel="editFormVisible = false" @submit="afterEditSubmit" />
|
||||
</mdp-dialog>
|
||||
<mdp-dialog title="新增项目预算" v-model="addFormVisible" width="60%" append-to-body :close-on-click-modal="false">
|
||||
<XmBudgetRecordAdd sub-op-type="add" :selProject="project||(params.projectId?{id:params.projectId,name:params.projectId}:null)" :visible="addFormVisible"
|
||||
@cancel="addFormVisible = false" @submit="afterAddSubmit" />
|
||||
</mdp-dialog>
|
||||
<!--新增 XmBudgetRecord 项目成本预算界面-->
|
||||
<mdp-dialog ref="splitDlg" title="拆分项目预算" width="60%" append-to-body :close-on-click-modal="false">
|
||||
<template #default="{dialog,data}">
|
||||
<XmBudgetRecordSplit sub-op-type="split" :formData="data.formData"
|
||||
@cancel="dialog.close()" @submit="afterAddSubmit;dialog.close()" />
|
||||
</template>
|
||||
</mdp-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util';//全局公共库
|
||||
import config from '@/api/mdp_pub/mdp_config';//全局公共库
|
||||
import { listXmBudgetRecord, delXmBudgetRecord, batchDelXmBudgetRecord, editSomeFieldsXmBudgetRecord, addXmBudgetRecord, editXmBudgetRecord } from '@/api/xm/pro/xmBudgetRecord';
|
||||
import XmBudgetRecordEdit from './EditForm.vue';//新增修改界面
|
||||
import XmBudgetRecordAdd from './AddForm.vue';//新增修改界面
|
||||
import XmBudgetRecordSplit from './SplitForm.vue';//新增修改界面
|
||||
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
import { MdpTableMixin } from '@/components/mdp-ui/mixin/MdpTableMixin.js'
|
||||
|
||||
import XmProjectSelect from '@/views/xm/core/components/XmProjectSelect.vue'
|
||||
export default {
|
||||
mixins: [MdpTableMixin],
|
||||
name: 'xmBudgetRecordMng',
|
||||
components: {
|
||||
XmBudgetRecordEdit, XmBudgetRecordAdd, XmProjectSelect,XmBudgetRecordSplit
|
||||
},
|
||||
props: ['visible', "selProject"],
|
||||
computed: {
|
||||
...mapState(useUserStore, ['userInfo']),
|
||||
|
||||
},
|
||||
watch: {
|
||||
visible(val) {
|
||||
if (val == true) {
|
||||
this.initData();
|
||||
this.searchTableDatas()
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filters: {
|
||||
name: '',
|
||||
remark: '',
|
||||
subjectId: '',
|
||||
startBizMonth:'',
|
||||
endBizMonth:'',
|
||||
projectId:'',
|
||||
},
|
||||
addForm: {
|
||||
projectId: '', userid: '', budgetAt: '', id: '', remark: '', username: '', subjectId: '', bizSdate: '', bizEdate: '', bizMonth: '', instId: '', bizFlowState: '', costType: '', subjectName: '', branchId: '', ubranchId: ''
|
||||
},
|
||||
editForm: {
|
||||
projectId: '', userid: '', budgetAt: '', id: '', remark: '', username: '', subjectId: '', bizSdate: '', bizEdate: '', bizMonth: '', instId: '', bizFlowState: '', costType: '', subjectName: '', branchId: '', ubranchId: ''
|
||||
},
|
||||
apis: {
|
||||
list: listXmBudgetRecord,
|
||||
add: addXmBudgetRecord,
|
||||
edit: editXmBudgetRecord,
|
||||
del: delXmBudgetRecord,
|
||||
batchDel: batchDelXmBudgetRecord,
|
||||
editSomeFields: editSomeFieldsXmBudgetRecord,
|
||||
},
|
||||
}
|
||||
},//end data
|
||||
methods: {
|
||||
//获取列表 XmBudgetRecord 项目成本预算
|
||||
preQueryParamCheck(params) {
|
||||
return true;
|
||||
},
|
||||
editSomeFieldsCheck(row, fieldName, $event, params) {
|
||||
|
||||
params[fieldName] = $event
|
||||
return true;
|
||||
},
|
||||
initCurrData: function () {
|
||||
|
||||
},
|
||||
showAdd(){
|
||||
if(!this.project?.id && !this.params.projectId){
|
||||
this.$message.warning("请先选中项目")
|
||||
return
|
||||
}
|
||||
this.addFormVisible=true
|
||||
},
|
||||
showSplit(row){
|
||||
this.editForm=row
|
||||
this.$refs.splitDlg.open({formData:row})
|
||||
}
|
||||
|
||||
},//end methods
|
||||
mounted() {
|
||||
this.filters.startBizMonth=this.$mdp.moment().startOf('year').format("YYYY-MM")
|
||||
this.filters.endBizMonth=this.$mdp.moment().endOf('year').format("YYYY-MM")
|
||||
this.searchTableDatas();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped />
|
||||
@@ -1,37 +1,60 @@
|
||||
<template>
|
||||
|
||||
<el-row class="page-header" />
|
||||
<el-row class="page-main" :style="{overflowX:'auto',height:maxTableHeight+'px'}" ref="table">
|
||||
<!--编辑界面 XmBudgetNlabor 项目人力成本预算-->
|
||||
<!--编辑界面 XmBudgetRecord 项目人力成本预算-->
|
||||
<el-form :model="editForm" label-width="120px" :rules="editFormRules" ref="editFormRef">
|
||||
<el-form-item label="预算总金额" prop="totalBudgetAt">
|
||||
¥<el-input type="number" style="width:40%;" v-model="totalBudgetAt" placeholder="预算金额"/> 元
|
||||
平均 ¥{{editForm.budgetAt}} 元 / 月
|
||||
|
||||
<el-form-item label="成本中心" prop="costCenterId">
|
||||
<MdpSelectDept width="100%" v-model="editForm.costCenterId" placeholder="成本中心" title="成本中心"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="原预算科目" prop="subjectId">
|
||||
<mdp-select width="100%" item-code="projectSubject" placeholder="预算科目编号" :modelValue="formData.subjectId"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用途说明" prop="remark">
|
||||
<el-input v-model="editForm.remark" placeholder="备注" />
|
||||
<el-form-item label="原预算总金额">
|
||||
{{formData?.budgetAt||0}}元,{{ parseInt((formData?.budgetAt||0)/10000) }}万元
|
||||
</el-form-item>
|
||||
<el-form-item label="拆分总金额">
|
||||
<el-input type="number" v-model="totalBudgetAt" placeholder="拆分金额">
|
||||
<template #suffix>元,{{ parseInt(totalBudgetAt/10000) }}万元</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="新预算科目" prop="subjectId">
|
||||
<mdp-select width="100%" item-code="projectSubject" placeholder="预算科目编号" :modelValue="editForm.subjectId"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预算科目" prop="subjectId">
|
||||
<mdp-select item-code="projectSubject" placeholder="预算科目编号" v-model="editForm.subjectId"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="分摊月份" prop="bizMonth">
|
||||
<el-space wrap fill>
|
||||
<el-date-picker
|
||||
v-model="bizYear"
|
||||
type="year"
|
||||
value-format="yyyy"
|
||||
value-format="YYYY"
|
||||
placeholder="选择年" />
|
||||
<div style="margin-top: 20px">
|
||||
<el-checkbox-group v-model="bizMonths" size="medium">
|
||||
<div>
|
||||
<el-checkbox-group v-model="bizMonths" >
|
||||
<el-checkbox-button v-for="i in bizMonthList" :label="i" :key="i">{{i}}</el-checkbox-button>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
<div style="padding-top:20px;">下一年:{{secBizYear}}</div>
|
||||
<div style="margin-top: 20px">
|
||||
<el-checkbox-group v-model="secBizMonths" size="medium">
|
||||
</div>
|
||||
<div>下一年:{{secBizYear}}</div>
|
||||
<div>
|
||||
<el-checkbox-group v-model="secBizMonths" >
|
||||
<el-checkbox-button v-for="i in bizMonthList" :label="i" :key="i">{{i}}</el-checkbox-button>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-space>
|
||||
</el-form-item>
|
||||
<el-form-item label="预算金额" prop="budgetAt">
|
||||
<div>{{ editForm.budgetAt||0 }} <el-text type="primary">元/每月</el-text>
|
||||
</div>
|
||||
<div>
|
||||
<el-text type="info"> {{ parseInt((editForm.budgetAt||0)/10000) }} 万元/每月</el-text>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="费用主责" prop="userid">
|
||||
<MdpSelectUser width="100%" v-model="editForm.userid" :init-name="editForm.username" @change2="($event)=>editForm.username=$event?.username" />
|
||||
<el-text type="primary">如果无法确定具体人员,请在备注说明,方便后续修正</el-text>
|
||||
</el-form-item>
|
||||
<el-form-item label="用途说明" prop="remark">
|
||||
<el-input type="textarea" v-model="editForm.remark" placeholder="备注" />
|
||||
</el-form-item>
|
||||
<!--
|
||||
<el-form-item label="成本类型" prop="costType">
|
||||
<template>
|
||||
@@ -42,24 +65,23 @@
|
||||
</el-form-item>
|
||||
-->
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<el-row class="page-bottom bottom-fixed">
|
||||
<div class="footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button v-loading="load.edit" type="primary" @click="saveSubmit" :disabled="load.edit==true">提交</el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util';//全局公共库
|
||||
import config from "@/api/mdp_pub/mdp_config"; //全局公共库import
|
||||
import { addXmBudgetNlabor,editXmBudgetNlabor,batchAddXmBudgetNlabor } from '@/api/xm/pro/xmBudgetNlabor';
|
||||
<script>
|
||||
import { splitXmBudgetRecord } from '@/api/xm/pro/xmBudgetRecord';
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
export default {
|
||||
name:'xmBudgetNlaborEdit',
|
||||
import {MdpFormMixin} from "@/components/mdp-ui/mixin/MdpFormMixin.js"
|
||||
export default {
|
||||
mixins:[MdpFormMixin],
|
||||
name:'XmBudgetRecordAdd',
|
||||
components: {
|
||||
|
||||
},
|
||||
@@ -78,17 +100,17 @@ import { useUserStore } from '@/store/modules/user'
|
||||
if(!this.totalBudgetAt){
|
||||
return 0;
|
||||
}
|
||||
return Math.round(parseFloat(this.totalBudgetAt)/this.allMonths.length);
|
||||
return parseFloat(this.totalBudgetAt)/this.allMonths.length;
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
props:['xmBudgetNlabor','visible','opType','selProject'],
|
||||
props:['formData','visible','subOpType'],
|
||||
|
||||
watch: {
|
||||
'xmBudgetNlabor':function( xmBudgetNlabor ) {
|
||||
if(xmBudgetNlabor){
|
||||
this.editForm = {...xmBudgetNlabor};
|
||||
'formData':function( formData ) {
|
||||
if(formData){
|
||||
this.editForm = {...formData};
|
||||
}
|
||||
|
||||
},
|
||||
@@ -103,47 +125,32 @@ import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
'budgetAt': function(budgetAt){
|
||||
this.editForm.budgetAt=budgetAt;
|
||||
} ,
|
||||
|
||||
'editForm.subjectId':function(subjectId) {
|
||||
var dicts=this.dicts.projectSubject.filter(i=>i.id==subjectId)
|
||||
if( dicts!=null && dicts.length>0 ){
|
||||
this.editForm.subjectName=dicts[0].name
|
||||
}else{
|
||||
this.editForm.subjectName="";
|
||||
}
|
||||
}
|
||||
} ,
|
||||
},
|
||||
data() {
|
||||
var year=new Date().getFullYear();
|
||||
var secYear=parseInt(year)+1;
|
||||
return {
|
||||
currOpType:'add',//add/edit
|
||||
load:{ list: false, edit: false, del: false, add: false },//查询中...
|
||||
dicts:{
|
||||
projectSubject:[],
|
||||
},//下拉选择框的所有静态数据 params={categoryId:'all',itemCodes:['sex']} 返回结果 {sex: [{id:'1',name:'男'},{id:'2',name:'女'}]}
|
||||
|
||||
editFormRules: {
|
||||
subjectId: [
|
||||
{ required: true, message: '科目不能为空', trigger: 'change' }
|
||||
],
|
||||
/**
|
||||
username: [
|
||||
{ required: true, message: '姓名不能为空', trigger: 'change' }
|
||||
],
|
||||
*/
|
||||
username: [
|
||||
{ required: true, message: '姓名不能为空,如果不确定具体人,请填写岗位代替', trigger: 'change' }
|
||||
],
|
||||
budgetAt: [
|
||||
{ required: true, message: '金额不能为空', trigger: 'change' }
|
||||
],
|
||||
|
||||
remark: [
|
||||
{ required: true, message: '用途说明不能为空', trigger: 'change' }
|
||||
]
|
||||
// remark: [
|
||||
// { required: true, message: '用途说明不能为空', trigger: 'change' }
|
||||
// ]
|
||||
},
|
||||
editForm: {
|
||||
id:'',projectId:'',budgetAt:'',remark:'',subjectId:'',bizSdate:'',bizEdate:'',instId:'',bizFlowState:'',costType:'',bizMonth:'',subjectName:'',branchId:''
|
||||
projectId:'',userid:'',budgetAt:'',id:'',remark:'',username:'',subjectId:'',bizSdate:'',bizEdate:'',bizMonth:'',instId:'',bizFlowState:'',costType:'',subjectName:'',branchId:'',ubranchId:''
|
||||
},
|
||||
maxTableHeight:300,
|
||||
|
||||
totalBudgetAt:0,
|
||||
bizYear:year+'',
|
||||
@@ -153,25 +160,20 @@ import { useUserStore } from '@/store/modules/user'
|
||||
bizMonthList:['01','02','03','04','05','06','07','08','09','10','11','12'],
|
||||
}//end return
|
||||
},//end data
|
||||
methods: {
|
||||
|
||||
...util,
|
||||
|
||||
// 取消按钮点击 父组件监听@cancel="editFormVisible=false" 监听
|
||||
handleCancel:function(){
|
||||
this.$refs['editFormRef'].resetFields();
|
||||
this.$emit('cancel');
|
||||
},
|
||||
//新增、编辑提交XmBudgetNlabor 项目人力成本预算父组件监听@submit="afterEditSubmit"
|
||||
methods: {
|
||||
//新增、编辑提交XmBudgetRecord 项目人力成本预算父组件监听@submit="afterEditSubmit"
|
||||
saveSubmit: function () {
|
||||
if(this.bizYear==null || this.bizYear==''){
|
||||
this.$notify({position:'bottom-left',showClose:true,message:"请选择需要分摊的年份", type: 'error' });
|
||||
return;
|
||||
}
|
||||
if(this.allMonths.length<=0){
|
||||
this.$notify({position:'bottom-left',showClose:true,message:"请选择需要分摊的月份", type: 'error' });
|
||||
return;
|
||||
}
|
||||
|
||||
var list=this.allMonths.map(i=>{
|
||||
let params = Object.assign({}, this.editForm);
|
||||
params.projectId=this.selProject.id
|
||||
let params = Object.assign({}, this.editForm);
|
||||
params.bizMonth=i
|
||||
|
||||
return params;
|
||||
@@ -181,14 +183,11 @@ import { useUserStore } from '@/store/modules/user'
|
||||
if (valid) {
|
||||
this.$confirm('确认提交吗?', '提示', {}).then(() => {
|
||||
this.load.edit=true
|
||||
var func=batchAddXmBudgetNlabor
|
||||
func(list).then((res) => {
|
||||
var func=splitXmBudgetRecord
|
||||
func({parentId:this.formData.id,splits:list}).then((res) => {
|
||||
this.load.edit=false
|
||||
var tips=res.tips;
|
||||
if(tips.isOk){
|
||||
this.editForm=res.data
|
||||
this.initData()
|
||||
this.currOpType="edit";
|
||||
this.$emit('submit');// @submit="afterAddSubmit"
|
||||
}
|
||||
this.$notify({ position:'bottom-left',showClose:true, message: tips.msg, type: tips.isOk?'success':'error' });
|
||||
@@ -199,25 +198,13 @@ import { useUserStore } from '@/store/modules/user'
|
||||
}
|
||||
});
|
||||
},
|
||||
initData: function(){
|
||||
this.currOpType=this.opType
|
||||
if(this.xmBudgetNlabor){
|
||||
this.editForm = Object.assign({},this.xmBudgetNlabor);
|
||||
}
|
||||
|
||||
if(this.opType=='edit'){
|
||||
|
||||
}else{
|
||||
|
||||
}
|
||||
},
|
||||
initCurrData: function(){
|
||||
this.totalBudgetAt=this.formData.budgetAt
|
||||
this.bizYear=this.formData.bizMonth.substring(0,4)
|
||||
}
|
||||
|
||||
},//end method
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initData()
|
||||
//this.maxTableHeight =util.calcTableMaxHeight(this.$refs.table.$el)
|
||||
});
|
||||
mounted() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<template #header>
|
||||
<el-space>
|
||||
<mdp-hi-query ref="hiQueryBtn" :column-configs="columnConfigs" v-model="hiQueryParams"
|
||||
@change="onHiQueryParamsChange" />
|
||||
<el-button icon="zoom-out" @click="searchReset()" title="重置查询条件并查询" ref="searchResetBtn" />
|
||||
|
||||
|
||||
<el-button icon="download" @click="export2Excel()" title="导出当前结果数据" plain ref="downloadBtn" />
|
||||
<mdp-table-configs :column-configs="columnConfigs" v-model="checkedColumns" ref="columnConfigsBtn" />
|
||||
|
||||
<el-button type="primary" @click="showAdd" icon="plus" plain />
|
||||
<el-button type="danger" v-loading="load.del" @click="batchDel" :disabled="this.sels.length === 0 || load.del == true"
|
||||
icon="delete" plain />
|
||||
</el-space>
|
||||
</template>
|
||||
|
||||
<el-space>
|
||||
<el-input v-model="filters.key" style="width: 20%;" placeholder="模糊查询" />
|
||||
<el-button v-loading="load.list" :disabled="load.list == true" @click="searchTableDatas" icon="search">查询</el-button>
|
||||
|
||||
</el-space>
|
||||
</ContentWrap>
|
||||
<!--列表 XmCostNlabor 项目实际人工成本费用-->
|
||||
<el-table ref="tableDatas" :data="tableDatas" v-adaptive="{ bottom: 50 }" @sort-change="sortChange" highlight-current-row
|
||||
v-loading="load.list" border @selection-change="selsChange" @row-click="rowClick" style="width: 100%;">
|
||||
<el-table-column type="selection" width="55" show-overflow-tooltip fixed="left" />
|
||||
<el-table-column sortable type="index" width="55" show-overflow-tooltip fixed="left" />
|
||||
<!--
|
||||
<el-table-column sortable prop="username" width="55" show-overflow-tooltip fixed="left">
|
||||
<span class="cell-text"> {{scope.row.username}}} </span>
|
||||
<span class="cell-bar"><el-input style="display:inline;" v-model="scope.row.username" placeholder="" @change="editSomeFields(scope.row,'username',$event)" :maxlength="22"/></span>
|
||||
</el-table-column>
|
||||
-->
|
||||
<el-table-column prop="projectName" label="项目名称" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span> {{ scope.row.projectName }} </span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="username" label="费用主责" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="cell-text"> {{ scope.row.username }} </span>
|
||||
<span class="cell-bar"><el-input style="display:inline;" v-model="scope.row.username" placeholder=""
|
||||
@change="editSomeFields(scope.row, 'username', $event)" :maxlength="22" /></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="用途说明" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="cell-text"> {{ scope.row.remark }} </span>
|
||||
<span class="cell-bar"><el-input style="display:inline;" v-model="scope.row.remark" placeholder=""
|
||||
@change="editSomeFields(scope.row, 'remark', $event)" :maxlength="22" /></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="actAt" label="实际金额" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="cell-text"> {{ scope.row.actAt }} </span>
|
||||
<span class="cell-bar"><el-input type="number" style="display:inline;" v-model="scope.row.actAt" placeholder=""
|
||||
@change="editSomeFields(scope.row, 'actAt', $event)" :maxlength="22" /></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="subjectId" label="成本科目" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<mdp-select item-code="projectSubject" width="100%" show-style="tag" v-model="scope.row.subjectId" placeholder="成本科目" @change="editSomeFields(scope.row, 'subjectId', $event)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bizMonth" label="费用月份" min-width="80" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span class="cell-text"> {{ scope.row.bizMonth }} </span>
|
||||
<span class="cell-bar">
|
||||
<el-date-picker @change="editSomeFields(scope.row, 'bizMonth', $event)" v-model="scope.row.bizMonth" type="month"
|
||||
value-format="yyyy-MM" placeholder="选择年月" />
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" @click="showEdit(scope.row, scope.$index)" icon="edit" plain />
|
||||
<el-button type="danger" @click="handleDel(scope.row, scope.$index)" icon="delete" plain />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination layout="total, sizes, prev, pager, next" @current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100, 500]" :current-page="pageInfo.pageNum"
|
||||
:page-size="pageInfo.pageSize" :total="pageInfo.total" style="float:right;" />
|
||||
|
||||
<!--编辑 XmCostNlabor 项目实际人工成本费用界面-->
|
||||
<mdp-dialog title="编辑项目非人力费用" v-model="editFormVisible" width="60%" append-to-body :close-on-click-modal="false">
|
||||
<xm-cost-nlabor-edit sub-op-type="edit" :formData="editForm" :visible="editFormVisible"
|
||||
@cancel="editFormVisible = false" @submit="afterEditSubmit" />
|
||||
</mdp-dialog>
|
||||
|
||||
<!--新增 XmCostNlabor 项目实际人工成本费用界面-->
|
||||
<mdp-dialog title="新增项目非人力费用" v-model="addFormVisible" width="60%" append-to-body :close-on-click-modal="false">
|
||||
<xm-cost-nlabor-edit sub-op-type="add" :sel-project="selProject" :visible="addFormVisible" @cancel="addFormVisible = false"
|
||||
@submit="afterAddSubmit" />
|
||||
</mdp-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util';//全局公共库
|
||||
import config from '@/api/mdp_pub/mdp_config';//全局公共库
|
||||
import { listXmCostNlabor, delXmCostNlabor, batchDelXmCostNlabor, editSomeFieldsXmCostNlabor } from '@/api/xm/pro/xmCostNlabor';
|
||||
import XmCostNlaborEdit from './XmCostNlaborEdit.vue';//新增修改界面
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import { MdpTableMixin } from '@/components/mdp-ui/mixin/MdpTableMixin.js'
|
||||
|
||||
export default {
|
||||
mixins: [MdpTableMixin],
|
||||
name: 'xmCostNlaborMng',
|
||||
components: {
|
||||
XmCostNlaborEdit,
|
||||
},
|
||||
props: ['visible', 'selProject'],
|
||||
computed: {
|
||||
...mapState(useUserStore, ['userInfo']),
|
||||
|
||||
},
|
||||
watch: {
|
||||
visible(val) {
|
||||
if (val == true) {
|
||||
this.initData();
|
||||
this.searchTableDatas()
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filters: {
|
||||
key: ''
|
||||
},
|
||||
addFormVisible: false,//新增xmCostNlabor界面是否显示
|
||||
addForm: {
|
||||
projectId: '', userid: '', ctime: '', sendTime: '', username: '', projectName: '', remark: '', id: '', taskId: '', taskName: '', subjectId: '', bizSdate: '', bizEdate: '', actAt: '', costType: '', bizMonth: '', bizDate: '', subjectName: '', ubranchId: '', branchId: ''
|
||||
},
|
||||
|
||||
editFormVisible: false,//编辑界面是否显示
|
||||
editForm: {
|
||||
projectId: '', userid: '', ctime: '', sendTime: '', username: '', projectName: '', remark: '', id: '', taskId: '', taskName: '', subjectId: '', bizSdate: '', bizEdate: '', actAt: '', costType: '', bizMonth: '', bizDate: '', subjectName: '', ubranchId: '', branchId: ''
|
||||
},
|
||||
apis: {
|
||||
list: listXmCostNlabor,
|
||||
del: delXmCostNlabor,
|
||||
batchDel: batchDelXmCostNlabor,
|
||||
editSomeFields: editSomeFieldsXmCostNlabor,
|
||||
}
|
||||
}
|
||||
},//end data
|
||||
methods: {
|
||||
//获取列表 XmCostNlabor 项目实际人工成本费用
|
||||
preQueryParamCheck(params) {
|
||||
return true;
|
||||
},
|
||||
|
||||
//显示编辑界面 XmCostNlabor 项目实际人工成本费用
|
||||
showEdit: function (row, index) {
|
||||
this.editFormVisible = true;
|
||||
this.editForm = Object.assign({}, row);
|
||||
},
|
||||
//显示新增界面 XmCostNlabor 项目实际人工成本费用
|
||||
showAdd: function () {
|
||||
this.addFormVisible = true;
|
||||
//this.addForm=Object.assign({}, this.editForm);
|
||||
},
|
||||
|
||||
editSomeFieldsCheck(row, fieldName, $event, params) {
|
||||
return true;
|
||||
},
|
||||
|
||||
initCurrData: function () {
|
||||
this.searchTableDatas()
|
||||
},
|
||||
|
||||
},//end methods
|
||||
mounted() {
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped />
|
||||
@@ -1,24 +1,28 @@
|
||||
<template>
|
||||
<!--编辑界面 XmCostNlabor 项目实际人工成本费用-->
|
||||
<!--编辑界面 XmCostRecord 项目实际人工成本费用-->
|
||||
<el-form :model="editForm" label-width="120px" :rules="editFormRules" ref="editFormRef">
|
||||
<el-form-item label="项目编号" prop="projectId" v-if="currOpType != 'add'">
|
||||
<el-input v-model="editForm.projectId" placeholder="项目编号" :maxlength="50" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目编号" prop="projectId" v-if="currOpType == 'add'">
|
||||
<XmProjectSelect width="100%" v-model="editForm.projectId" @change2="($event) => editForm.projectName = $event?.name || ''" />
|
||||
<XmProjectSelect width="100%" v-model="editForm.projectId" @change2="($event) => editForm.projectName = $event?.name || ''" :disabled="selProject?.id"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="费用主责" prop="username">
|
||||
<MdpSelectUser width="100%" v-model="editForm.userid" @change2="($event)=>editForm.username=$event?.username" />
|
||||
<MdpSelectUser width="100%" v-model="editForm.userid" :init-name="editForm.username" @change2="($event)=>editForm.username=$event?.username" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用途说明" prop="remark">
|
||||
<el-input v-model="editForm.remark" placeholder="用途说明" />
|
||||
<el-input type="textarea" v-model="editForm.remark" placeholder="用途说明" />
|
||||
</el-form-item>
|
||||
<el-form-item label="实际金额" prop="actAt">
|
||||
<el-input type="number" v-model="editForm.actAt" placeholder="实际金额" :maxlength="10" />
|
||||
</el-form-item>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="成本科目" prop="subjectId">
|
||||
<mdp-select item-code="projectSubject" width="100%" placeholder="科目编号" v-model="editForm.subjectId" />
|
||||
</el-form-item>
|
||||
<el-form-item label="成本中心" prop="costCenterId">
|
||||
<MdpSelectDept width="100%" v-model="editForm.costCenterId" placeholder="成本中心" title="成本中心"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="发生日期" prop="bizDate">
|
||||
<MdpDate v-model="editForm.bizDate" type="date" value-format="YYYY-MM-DD" placeholder="选择日期" autoDefault/>
|
||||
</el-form-item>
|
||||
@@ -33,14 +37,14 @@
|
||||
<script>
|
||||
import util from '@/components/mdp-ui/js/util';//全局公共库
|
||||
import config from "@/api/mdp_pub/mdp_config"; //全局公共库import
|
||||
import { addXmCostNlabor, editXmCostNlabor } from '@/api/xm/pro/xmCostNlabor';
|
||||
import { addXmCostRecord, editXmCostRecord } from '@/api/xm/pro/xmCostRecord';
|
||||
import { mapState } from 'pinia'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import XmProjectSelect from '../../core/components/XmProjectSelect.vue';
|
||||
import {MdpFormMixin} from "@/components/mdp-ui/mixin/MdpFormMixin.js"
|
||||
export default {
|
||||
mixins:[MdpFormMixin],
|
||||
name: 'xmCostNlaborEdit',
|
||||
name: 'xmCostRecordEdit',
|
||||
components: {
|
||||
XmProjectSelect
|
||||
},
|
||||
@@ -86,8 +90,8 @@ export default {
|
||||
projectId: '', userid: '', ctime: '', sendTime: '', username: '', projectName: '', remark: '', id: '', taskId: '', taskName: '', subjectId: '', bizSdate: '', bizEdate: '', actAt: '', costType: '', bizMonth: '', bizDate: '', subjectName: '', ubranchId: '', branchId: ''
|
||||
},
|
||||
apis:{
|
||||
add: addXmCostNlabor,
|
||||
edit: editXmCostNlabor,
|
||||
add: addXmCostRecord,
|
||||
edit: editXmCostRecord,
|
||||
}
|
||||
}//end return
|
||||
},//end data
|
||||