You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

392 lines
12 KiB

4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
  1. <template>
  2. <section>
  3. <el-row :gutter="5" >
  4. <el-col :span="showParams?23:24">
  5. <div>
  6. <div class="echart-box" :id="this.id"></div>
  7. <div class="progress"></div>
  8. </div>
  9. </el-col>
  10. <el-col :span="showParams?1:0" v-if="showParams">
  11. <el-popover trigger="manual" v-model="filterVisible" style="float:right;" width="500">
  12. <el-button slot="reference" style="margin-top:10px;margin-right:10px;z-index: 99999;" icon="el-icon-more" @click="filterVisible=!filterVisible"></el-button>
  13. <el-row>
  14. <el-button type="danger" icon="el-icon-delete" @click="$emit('delete',cfg)">从报告移出该报表</el-button>
  15. <el-button icon="el-icon-close" style="float:right;" @click="filterVisible=false">关闭</el-button>
  16. </el-row>
  17. <el-row>
  18. <el-form :model="params" class="padding" :style="{width:'100%',overflow: 'auto'}" ref="filtersRef">
  19. <el-row>
  20. <el-col :span="15">
  21. <el-form-item label="分组属性">
  22. <el-select style="width:100px;" size="small" v-model="params.groupBy" @change="onXmTaskSomeFieldsChange('groupBy',$event)" clearable>
  23. <el-option v-for="i in this.groupBys" :label="i.name" :key="i.id" :value="i.id"></el-option>
  24. </el-select>
  25. </el-form-item>
  26. <el-form-item label="归属项目" >
  27. <xm-project-select v-if="!xmProject || !xmProject.id" ref="xmProjectSelect" style="display:inline;" :auto-select="false" :link-project-id="xmProject?xmProject.id:null" @row-click="onProjectSelected" @clear="onProjectClear"></xm-project-select>
  28. <span v-else>{{xmProject.id}} <span v-if="xmProject.name"><br/>{{ xmProject.name }} </span> </span>
  29. </el-form-item>
  30. </el-col>
  31. <el-col :span="9">
  32. <el-form-item label="任务状态" prop="taskState">
  33. <el-select style="width:100px;" size="small" v-model="params.taskState" @change="onXmTaskSomeFieldsChange('taskState',$event)" clearable>
  34. <el-option v-for="i in this.dicts.taskState" :label="i.name" :key="i.id" :value="i.id"></el-option>
  35. </el-select>
  36. </el-form-item>
  37. <el-form-item label="任务类型" prop="taskType" >
  38. <el-select style="width:100px;" size="small" v-model="params.taskType" @change="onXmTaskSomeFieldsChange('taskType',$event)" clearable>
  39. <el-option v-for="i in this.dicts.taskType" :label="i.name" :key="i.id" :value="i.id"></el-option>
  40. </el-select>
  41. </el-form-item>
  42. <el-form-item label="任务来源" prop="planType">
  43. <el-select style="width:100px;" size="small" v-model="params.planType" @change="onXmTaskSomeFieldsChange('planType',$event)" clearable>
  44. <el-option v-for="i in this.dicts.planType" :label="i.name" :key="i.id" :value="i.id"></el-option>
  45. </el-select>
  46. </el-form-item>
  47. <el-form-item label="任务层次" prop="settleSchemel" >
  48. <el-select style="width:100px;" size="small" v-model="params.settleSchemel" @change="onXmTaskSomeFieldsChange('settleSchemel',$event)" clearable>
  49. <el-option v-for="i in this.dicts.xmTaskSettleSchemel" :label="i.name" :key="i.id" :value="i.id"></el-option>
  50. </el-select>
  51. </el-form-item>
  52. <el-form-item label="优先级别" prop="priority" >
  53. <el-select style="width:100px;" size="small" v-model="params.priority" @change="onXmTaskSomeFieldsChange('priority',$event)" clearable>
  54. <el-option v-for="i in dicts.priority" :label="i.name" :key="i.id" :value="i.id"></el-option>
  55. </el-select>
  56. </el-form-item>
  57. </el-col>
  58. </el-row>
  59. <el-form-item>
  60. <el-button type="primary" style="float:right;" icon="el-icon-search" @click="searchXmTaskAttDist">查询</el-button>
  61. </el-form-item>
  62. </el-form>
  63. </el-row>
  64. </el-popover>
  65. </el-col>
  66. </el-row>
  67. </section>
  68. </template>
  69. <script>
  70. import util from '@/common/js/util';//全局公共库
  71. import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询
  72. import { mapGetters } from 'vuex'
  73. import { getXmTaskAttDist } from '@/api/xm/core/xmTask';
  74. import XmProjectSelect from '@/views/xm/core/components/XmProjectSelect';//新增界面
  75. export default {
  76. components: {
  77. XmProjectSelect,
  78. },
  79. props:['id','cfg','category','showToolBar','showParams','isRptCfg','rptDatas','xmProduct','xmIteration','xmProject'],
  80. computed: {
  81. ...mapGetters([
  82. 'userInfo','roles'
  83. ]),
  84. rawDatasCpd(){
  85. if(this.rawDatas.length==0){
  86. return []
  87. }else{
  88. var itemId="";
  89. if(this.params.groupBy=='task_state'){
  90. itemId="taskState"
  91. }else if(this.params.groupBy=='settle_schemel'){
  92. itemId="xmTaskSettleSchemel"
  93. }else if(this.params.groupBy=='task_type'){
  94. itemId="taskType"
  95. }else if(this.params.groupBy=='priority'){
  96. itemId="priority"
  97. }else if(this.params.groupBy=='plan_type'){
  98. itemId="planType"
  99. }
  100. return this.rawDatas.map(i=>{
  101. var data={...i}
  102. data.name=this.formatDict(itemId,data.name)
  103. return data;
  104. })
  105. }
  106. },
  107. total(){
  108. if(!this.rawDatas || this.rawDatas.length==0){
  109. return 0
  110. }else{
  111. return this.rawDatas.reduce((n, i) => {
  112. return (n += i.value);
  113. }, 0)
  114. }
  115. },
  116. titleCpd(){
  117. var preName=""
  118. if(this.filters.testPlan && this.filters.testPlan.id){
  119. preName=`测试计划【${this.filters.testPlan.name}`
  120. }else if(this.filters.testCasedb && this.filters.testCasedb.id){
  121. preName=`测试库【${this.filters.testCasedb.name}`
  122. }else if(this.filters.iteration && this.filters.iteration.id){
  123. preName=`迭代【${this.filters.iteration.iterationName}`
  124. }else if(this.filters.project && this.filters.project.id){
  125. if(this.filters.project.name){
  126. preName=`项目【${this.filters.project.name}`
  127. }else{
  128. preName=`项目【${this.filters.project.id}`
  129. }
  130. }else if(this.filters.product && this.filters.product.id){
  131. if(this.filters.product.productName){
  132. preName=`产品【${this.filters.product.productName}`
  133. }else{
  134. preName=`产品【${this.filters.product.id}`
  135. }
  136. }
  137. return preName+this.groupBys.find(i=>i.id==this.params.groupBy).name+'数量分布'
  138. },
  139. legendCpd(){
  140. var itemId="";
  141. if(this.params.groupBy=='task_state'){
  142. itemId="taskState"
  143. }else if(this.params.groupBy=='settle_schemel'){
  144. itemId="xmTaskSettleSchemel"
  145. }else if(this.params.groupBy=='task_type'){
  146. itemId="taskType"
  147. }else if(this.params.groupBy=='priority'){
  148. itemId="priority"
  149. }else if(this.params.groupBy=='plan_type'){
  150. itemId="planType"
  151. }
  152. return this.dicts[itemId].map(i=>i.name)
  153. }
  154. },
  155. watch: {
  156. rawDatasCpd(){
  157. this.drawCharts();
  158. }
  159. },
  160. data() {
  161. return {
  162. filterVisible:false,
  163. filters:{
  164. product:null,
  165. project:null,
  166. testPlan:null,
  167. iteration:null,
  168. testCasedb:null,
  169. },
  170. params:{
  171. groupBy:'task_state',
  172. },
  173. title:'',//报表配置项
  174. remark:'', //报表配置项
  175. groupBys:[
  176. {id:'task_state', name:'任务状态'},
  177. {id:'task_type', name:'任务类型'},
  178. {id:'plan_type', name:'计划类型'},
  179. {id:'settle_schemel', name:'结算方案'},
  180. {id:'priority', name:'优先级别'}
  181. ],
  182. dicts:{},//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]}
  183. load:{ list: false, edit: false, del: false, add: false },//查询中...
  184. dateRanger:[],
  185. maxTableHeight:300,
  186. visible:false,
  187. rawDatas:[],
  188. }//end return
  189. },//end data
  190. methods: {
  191. formatDict(itemId,val){
  192. var dict=this.dicts[itemId]
  193. if(dict){
  194. var item=dict.find(i=>i.id==val)
  195. if(item){
  196. return item.name
  197. }
  198. }
  199. return val;
  200. },
  201. findMax( list ) {
  202. var i, max = list[0];
  203. if(list.length < 2) return max;
  204. for (i = 0; i < list.length; i++) {
  205. if (list[i].distBudgetWorkload > max.distBudgetWorkload) {
  206. max = list[i];
  207. }
  208. }
  209. return max;
  210. },
  211. open(){
  212. this.visible=true;
  213. this.filters.testPlan=this.xmTestPlan
  214. this.filters.product=this.xmProduct
  215. this.filters.project=this.xmProject
  216. this.filters.iteration=this.xmIteration
  217. this.filters.testCasedb=this.xmTestCasedb
  218. if( this.filters.testPlan && this.filters.testPlan.id){
  219. this.params.planId= this.filters.testPlan.id
  220. }
  221. if( this.filters.product && this.filters.product.id){
  222. this.params.productId= this.filters.product.id
  223. }
  224. if( this.filters.project && this.filters.project.id){
  225. this.params.projectId= this.filters.project.id
  226. }
  227. if( this.filters.iteration && this.filters.iteration.id){
  228. this.params.iterationId= this.filters.iteration.id
  229. }
  230. if( this.filters.testCasedb && this.filters.testCasedb.id){
  231. this.params.casedbId= this.filters.testCasedb.id
  232. }
  233. if(this.initGroupBy){
  234. this.params.groupBy=this.initGroupBy
  235. }
  236. if(this.cfg && this.cfg.id){
  237. this.params=this.cfg.params
  238. this.title=this.cfg.title
  239. this.remark=this.cfg.remark
  240. }
  241. if(this.showToolBar && !this.title){
  242. this.title="企业工作项每日趋势图"
  243. }
  244. this.searchXmTaskAttDist()
  245. },
  246. drawCharts() {
  247. this.myChart = this.$echarts.init(document.getElementById(this.id));
  248. this.myChart.setOption(
  249. {
  250. title: {
  251. text: this.titleCpd,
  252. left: 'center'
  253. },
  254. tooltip: {
  255. trigger: 'item',
  256. },
  257. toolbox: {
  258. show: true,
  259. top:"5%",
  260. right:"10px",
  261. feature: {
  262. dataView: { show: true, readOnly: false },
  263. saveAsImage: { show: true },
  264. }
  265. },
  266. calculable: true,
  267. legend:{
  268. bottom: 'bottom',
  269. data:this.legendCpd,
  270. },
  271. graphic: {
  272. type: 'text',
  273. left: 'center',
  274. top: 'center',
  275. style: {
  276. // text: '总数',
  277. text:
  278. '任务数'+this.total ,
  279. textAlign: 'center',
  280. fill: '#333',
  281. width: 30,
  282. height: 30,
  283. fontSize: 14
  284. }
  285. },
  286. series: [
  287. {
  288. type: 'pie',
  289. radius: ['50%','70%'],
  290. data: this.rawDatasCpd,
  291. emphasis: {
  292. itemStyle: {
  293. shadowBlur: 10,
  294. shadowOffsetX: 0,
  295. shadowColor: 'rgba(0, 0, 0, 0.5)'
  296. }
  297. },
  298. label: {
  299. show: true,
  300. formatter:'{b}: {c}  ({d}%)'
  301. },
  302. }
  303. ]
  304. }
  305. )
  306. },
  307. onXmTaskSomeFieldsChange(fieldName,$event){
  308. },
  309. searchXmTaskAttDist(){
  310. if(this.rptDatas){
  311. this.rawDatas=this.rptDatas
  312. return;
  313. }
  314. var params={...this.params}
  315. if(!params.groupBy){
  316. this.$notify({position:'bottom-left',showClose:true,message:'请选中分组属性',type:'warning'})
  317. return
  318. }
  319. params.ntype='0'
  320. getXmTaskAttDist(params).then(res=>{
  321. this.rawDatas=res.data.data
  322. })
  323. },
  324. onProjectSelected(project){
  325. this.filters.project=project
  326. },
  327. onProjectClear(){
  328. this.filters.project=null
  329. },
  330. onIterationSelected(iteration){
  331. this.filters.iteration=iteration
  332. },
  333. onIterationClear(){
  334. this.filters.iteration=null
  335. }
  336. },//end method
  337. mounted() {
  338. initSimpleDicts('all',['planType','xmTaskSettleSchemel','taskType','priority','taskState'] ).then(res=>{
  339. this.dicts=res.data.data;
  340. })
  341. //this.maxTableHeight = util.calcTableMaxHeight(this.$refs.filtersRef.$el)
  342. //this.charts();
  343. this.open();
  344. }//end mounted
  345. }
  346. </script>
  347. <style scoped>
  348. .image {
  349. width: 100%;
  350. display: block;
  351. }
  352. </style>