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.

415 lines
12 KiB

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