report.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. <template>
  2. <div class="app-container">
  3. <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
  4. <el-form-item label="公司名" prop="companyId">
  5. <el-select multiple filterable v-model="companyIdArr" placeholder="请选择公司名" clearable size="small">
  6. <el-option
  7. v-for="item in companys"
  8. :key="item.companyId"
  9. :label="item.companyName"
  10. :value="item.companyId"
  11. />
  12. </el-select>
  13. </el-form-item>
  14. <el-form-item >
  15. <treeselect style="width: 220px" :clearable="false" v-model="queryParams.deptId" :options="deptOptions" :show-count="true" placeholder="请选择归属部门" />
  16. </el-form-item>
  17. <el-form-item label="所属档期" prop="scheduleId">
  18. <el-select multiple style="width:205.4px" v-model="scheduleIdArr" placeholder="请选择档期" clearable size="small" >
  19. <el-option
  20. v-for="item in scheduleList"
  21. :key="item.id"
  22. :label="item.name"
  23. :value="item.id"
  24. />
  25. </el-select>
  26. </el-form-item>
  27. <!-- <el-form-item label="档期名称" prop="scheduleName">
  28. <el-input
  29. v-model="queryParams.name"
  30. placeholder="请输入档期名称"
  31. clearable
  32. size="small"
  33. @keyup.enter.native="handleQuery"
  34. />
  35. </el-form-item> -->
  36. <!-- <el-form-item label="档期状态" prop="scheduleStatus">
  37. <el-select v-model="queryParams.status" placeholder="请选择档期状态" clearable size="small">
  38. <el-option
  39. v-for="dict in statusOptions"
  40. :key="dict.dictValue"
  41. :label="dict.dictLabel"
  42. :value="dict.dictValue"
  43. />
  44. </el-select>
  45. </el-form-item> -->
  46. <el-form-item label="创建时间" prop="createTime">
  47. <el-date-picker
  48. style="width:225.4px"
  49. clearable size="small"
  50. v-model="dateRange"
  51. type="daterange"
  52. value-format="yyyy-MM-dd"
  53. start-placeholder="开始日期"
  54. end-placeholder="结束日期">
  55. </el-date-picker>
  56. </el-form-item>
  57. <el-form-item>
  58. <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  59. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  60. </el-form-item>
  61. </el-form>
  62. <el-row :gutter="10" class="mb8">
  63. <el-col :span="1.5">
  64. <el-button
  65. type="warning"
  66. icon="el-icon-download"
  67. size="mini"
  68. @click="handleExport"
  69. v-hasPermi="['company:tcmScheduleReport:export']"
  70. >导出</el-button>
  71. </el-col>
  72. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  73. </el-row>
  74. <el-table v-loading="loading" :data="tcmScheduleReportList" @selection-change="handleSelectionChange">
  75. <!-- <el-table-column type="expand" >
  76. <template slot-scope="scope">
  77. <el-table border :data="[scope.row]">
  78. <el-table-column prop="round1Money" label="一轮业绩" ></el-table-column>
  79. <el-table-column prop="round1Order" label="一轮单数"></el-table-column>
  80. <el-table-column prop="count" label="一轮转化率">
  81. <template slot-scope="scope1">
  82. {{(scope1.row.onlineRate*100).toFixed(2)+"%"}}
  83. </template>
  84. </el-table-column>
  85. <el-table-column prop="round2Unit" label="一轮客单"></el-table-column>
  86. </el-table>
  87. </template>
  88. </el-table-column> -->
  89. <el-table-column label="id" width="50" align="center" prop="id" />
  90. <el-table-column label="档期" align="center" prop="scheduleName" />
  91. <el-table-column label="公司名称" width="110" align="center" prop="companyName" />
  92. <el-table-column label="所在部门" width="110" align="center" prop="deptName" />
  93. <el-table-column label="员工姓名" align="center" prop="userNickName" />
  94. <el-table-column label="总进线" width="60" align="center" prop="totalNum" />
  95. <el-table-column label="注册数" width="60" align="center" prop="registerNum" />
  96. <el-table-column label="上线数" width="60" align="center" prop="onlineNum" />
  97. <el-table-column label="完课数" width="60" align="center" prop="finishNum" />
  98. <el-table-column label="注册率" width="80" align="center" prop="registerRate" >
  99. <template slot-scope="scope">
  100. {{ renderTotalVal(scope.row,0) }}
  101. </template>
  102. </el-table-column>
  103. <el-table-column label="上线率" width="80" align="center" prop="onlineRate" >
  104. <template slot-scope="scope">
  105. {{ renderTotalVal(scope.row,1) }}
  106. </template>
  107. </el-table-column>
  108. <el-table-column label="完课率" width="80" align="center" prop="finishRate" >
  109. <template slot-scope="scope">
  110. {{ renderTotalVal(scope.row,2) }}
  111. </template>
  112. </el-table-column>
  113. <el-table-column label="累计总业绩" width="90" align="center" prop="totalMoney" >
  114. <template slot-scope="scope">
  115. {{!scope.row.totalMoney?0:(scope.row.totalMoney).toFixed(2)}}
  116. </template>
  117. </el-table-column>
  118. <el-table-column label="累计总单" width="80" align="center" prop="totalOrder" >
  119. <template slot-scope="scope">
  120. {{!scope.row.totalOrder?0:scope.row.totalOrder}}
  121. </template>
  122. </el-table-column>
  123. <el-table-column label="目标业绩" width="80" align="center" prop="targetMoney" >
  124. <template slot-scope="scope">
  125. {{!scope.row.targetMoney?0:(scope.row.targetMoney).toFixed(2)}}
  126. </template>
  127. </el-table-column>
  128. <el-table-column label="目标完成率" width="90" align="center" prop="targetRate" >
  129. <template slot-scope="scope">
  130. {{ renderTotalVal(scope.row,3) }}
  131. </template>
  132. </el-table-column>
  133. <el-table-column label="创建时间" align="center" prop="createTime" width="100">
  134. <template slot-scope="scope">
  135. <span>{{ parseTime(scope.row.createTime) }}</span>
  136. </template>
  137. </el-table-column>
  138. <el-table-column v-for='index in 36' :key='index' :label="renderLabel(index-1)" :width="(index-1)%4==2?'85':'72'" :prop="renderLabelProp(index)" align="center" >
  139. <template slot-scope="scope">
  140. {{ runderValue(scope.row,index-1) }}
  141. </template>
  142. </el-table-column>
  143. <!-- <el-table-column fixed="right" label="操作" width="150px" align="center" class-name="small-padding fixed-width">
  144. <template slot-scope="scope">
  145. <el-button size="mini" type="text" @click="handleDetails(scope.row)">查看</el-button>
  146. <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['company:tcmScheduleReport:edit']">修改</el-button>
  147. <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['company:tcmScheduleReport:remove']">删除</el-button>
  148. </template>
  149. </el-table-column> -->
  150. </el-table>
  151. <pagination
  152. v-show="total>0"
  153. :total="total"
  154. :page.sync="queryParams.pageNum"
  155. :limit.sync="queryParams.pageSize"
  156. @pagination="getList"
  157. />
  158. </div>
  159. </template>
  160. <script>
  161. import { treeselect } from "@/api/company/companyDept";
  162. import Treeselect from "@riophae/vue-treeselect";
  163. import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  164. import { listTcmScheduleReport, exportTcmScheduleReport,listAllSchedule } from "@/api/company/scheduleReport";
  165. import { getCompanyList } from "@/api/company/company";
  166. export default {
  167. watch: {
  168. // 监听companyIdArr
  169. 'companyIdArr':'companyChange'
  170. },
  171. name: "TcmScheduleReport",
  172. components: { Treeselect },
  173. data() {
  174. return {
  175. // 遮罩层
  176. loading: true,
  177. // 选中数组
  178. ids: [],
  179. // 非单个禁用
  180. single: true,
  181. // 非多个禁用
  182. multiple: true,
  183. // 显示搜索条件
  184. showSearch: true,
  185. // 总条数
  186. total: 0,
  187. // 中医档期业绩报表表格数据
  188. tcmScheduleReportList: [],
  189. scheduleList:[],
  190. companyIdArr:[],
  191. scheduleIdArr:[],
  192. companys:[],
  193. roundArr:["一轮","二轮","三轮","四轮","五轮","六轮","七轮","八轮","九轮"],
  194. // 弹出层标题
  195. title: "",
  196. // 是否显示弹出层
  197. open: false,
  198. dateRange: [],
  199. // 查询参数
  200. queryParams: {
  201. pageNum: 1,
  202. pageSize: 10,
  203. scheduleId: null,
  204. deptId:null,
  205. userId: null,
  206. companyId: null,
  207. totalNum: null,
  208. registerNum: null,
  209. onlineNum: null,
  210. finishNum: null,
  211. registerRate: null,
  212. onlineRate: null,
  213. finishRate: null,
  214. totalMoney: null,
  215. },
  216. users:[],
  217. // 部门树选项
  218. deptOptions: [],
  219. // 部门名称
  220. deptName: undefined,
  221. // 表单参数
  222. form: {},
  223. // 表单校验
  224. rules: {
  225. }
  226. };
  227. },
  228. created() {
  229. getCompanyList().then(response => {
  230. this.companys = response.data;
  231. if(this.companys!=null&&this.companys.length>0){
  232. this.companyId=this.companys[0].companyId;
  233. this.getTreeselect();
  234. }
  235. });
  236. this.getListSchedule();
  237. this.getList();
  238. },
  239. methods: {
  240. renderLabel(index){
  241. var colls=parseInt(index/4);
  242. var cell=parseInt(index%4);
  243. var str=this.roundArr[colls];
  244. if(cell==0){
  245. str+="业绩"
  246. }
  247. else if(cell==1){
  248. str+="单数"
  249. }
  250. else if(cell==2){
  251. str+="转化率"
  252. }
  253. else if(cell==3){
  254. str+="客单"
  255. }
  256. return str;
  257. },
  258. renderLabelProp(index){
  259. var colls=parseInt(index/4)+1;
  260. var str=this.roundArr[colls];
  261. if(colls==1){
  262. str="round"+colls+"Money";
  263. }
  264. else if(colls==2){
  265. str="round"+colls+"Order";
  266. }
  267. else if(colls==3){
  268. str="round"+colls+"Rate";
  269. }
  270. else if(colls==4){
  271. str="round"+colls+"Unit";
  272. }
  273. return str;
  274. },
  275. runderValue(row,index){ //注册率=注册数/总进线 上线率=上线数/注册数 完课率=完课数/注册数 目标完成率=累计业绩/目标业绩 单线R值=累计业绩/总进线
  276. var colls=parseInt(index/4)+1;
  277. var cell=parseInt(index%4);
  278. var value=0;
  279. if(cell==0){ //业绩
  280. value=!row["round"+colls+"Money"]?0:(row["round"+colls+"Money"]).toFixed(2);
  281. }
  282. else if(cell==1){ //订单数
  283. value=row["round"+colls+"Order"];
  284. }
  285. else if(cell==2){ //转化率 =成单数/总进线
  286. value=(row["round"+colls+"Order"]/row["totalNum"]*100.0).toFixed(3)+"%";
  287. //value=(row["round"+colls+"Rate"]*100).toFixed(2)+"%";
  288. }
  289. else if(cell==3){ //客单=成交金额/成交单数
  290. var roundMoney=row["round"+colls+"Money"];
  291. var roundOrder=row["round"+colls+"Order"];
  292. if(!!roundMoney && !!roundOrder){
  293. value=(roundMoney/roundOrder*1.0).toFixed(2);
  294. }
  295. }
  296. return value;
  297. },
  298. renderTotalVal(row,index){
  299. var value=0;
  300. if(index==0){ //注册率=注册数/总进线
  301. value=(row["registerNum"]/row["totalNum"]*100.0).toFixed(3)+"%";
  302. }
  303. else if(index==1){ //上线率=上线数/注册数
  304. value=(row["onlineNum"]/row["registerNum"]*100.0).toFixed(3)+"%";
  305. }
  306. else if(index==2){ //完课率=完课数/注册数
  307. value=(row["finishNum"]/row["registerNum"]*100.0).toFixed(3)+"%";
  308. }
  309. else if(index==3){ //目标完成率=累计业绩/目标业绩
  310. if(row.targetMoney>0){
  311. value=(row.totalMoney/row.targetMoney*100.0).toFixed(3)+"%";
  312. }else{
  313. value="0%";
  314. }
  315. }
  316. else if(index==4){ //人均业绩=总业绩/当期部门人数
  317. value=(row["totalMoney"]/row["cuCount"]*1.0).toFixed(3);
  318. }
  319. else if(index==5){ //单线R值=累计业绩/总进线
  320. value=(row["targetMoney"]/row["totalNum"]*1.0).toFixed(3);
  321. }
  322. return value;
  323. },
  324. getListSchedule() {
  325. this.loading = true;
  326. listAllSchedule().then(response => {
  327. this.scheduleList = response.rows;
  328. });
  329. },
  330. /** 查询中医档期业绩报表列表 */
  331. getList() {
  332. this.queryParams.scheduleId="";
  333. this.queryParams.companyId="";
  334. if(this.scheduleIdArr.length>0){
  335. this.queryParams.scheduleId=this.scheduleIdArr.toString();
  336. }
  337. if(this.companyIdArr.length>0){
  338. this.queryParams.companyId=this.companyIdArr.toString();
  339. }
  340. this.loading = true;
  341. listTcmScheduleReport(this.addDateRange(this.queryParams,this.dateRange)).then(response => {
  342. this.tcmScheduleReportList = response.rows;
  343. this.total = response.total;
  344. this.loading = false;
  345. });
  346. },
  347. // 取消按钮
  348. cancel() {
  349. this.open = false;
  350. this.reset();
  351. },
  352. // 表单重置
  353. reset() {
  354. this.form = {
  355. id: null,
  356. scheduleId: null,
  357. userId: null,
  358. companyId: null,
  359. totalNum: null,
  360. registerNum: null,
  361. onlineNum: null,
  362. finishNum: null,
  363. registerRate: null,
  364. onlineRate: null,
  365. finishRate: null,
  366. totalMoney: null,
  367. totalOrder: null,
  368. targetMoney: null,
  369. targetRate: null,
  370. round1Money: null,
  371. round1Order: null,
  372. round1Rate: null,
  373. round1Unit: null,
  374. round2Money: null,
  375. round2Order: null,
  376. round2Rate: null,
  377. round2Unit: null,
  378. round3Money: null,
  379. round3Order: null,
  380. round3Rate: null,
  381. round3Unit: null,
  382. round4Money: null,
  383. round4Order: null,
  384. round4Rate: null,
  385. round4Unit: null,
  386. round5Money: null,
  387. round5Order: null,
  388. round5Rate: null,
  389. round5Unit: null,
  390. round6Money: null,
  391. round6Order: null,
  392. round6Rate: null,
  393. round6Unit: null,
  394. round7Money: null,
  395. round7Order: null,
  396. round7Rate: null,
  397. round7Unit: null,
  398. round8Money: null,
  399. round8Order: null,
  400. round8Rate: null,
  401. round8Unit: null,
  402. round9Money: null,
  403. round9Order: null,
  404. round9Rate: null,
  405. round9Unit: null
  406. };
  407. this.resetForm("form");
  408. },
  409. /** 搜索按钮操作 */
  410. handleQuery() {
  411. this.queryParams.pageNum = 1;
  412. this.getList();
  413. },
  414. /** 重置按钮操作 */
  415. resetQuery() {
  416. this.resetForm("queryForm");
  417. this.handleQuery();
  418. },
  419. // 多选框选中数据
  420. handleSelectionChange(selection) {
  421. this.ids = selection.map(item => item.id)
  422. this.single = selection.length!==1
  423. this.multiple = !selection.length
  424. },
  425. /** 新增按钮操作 */
  426. handleAdd() {
  427. this.reset();
  428. this.open = true;
  429. this.title = "添加中医档期业绩报表";
  430. },
  431. /** 修改按钮操作 */
  432. handleUpdate(row) {
  433. this.reset();
  434. const id = row.id || this.ids
  435. getTcmScheduleReport(id).then(response => {
  436. this.form = response.data;
  437. this.open = true;
  438. this.title = "修改中医档期业绩报表";
  439. });
  440. },
  441. /** 提交按钮 */
  442. submitForm() {
  443. this.$refs["form"].validate(valid => {
  444. if (valid) {
  445. if (this.form.id != null) {
  446. updateTcmScheduleReport(this.form).then(response => {
  447. if (response.code === 200) {
  448. this.msgSuccess("修改成功");
  449. this.open = false;
  450. this.getList();
  451. }
  452. });
  453. } else {
  454. addTcmScheduleReport(this.form).then(response => {
  455. if (response.code === 200) {
  456. this.msgSuccess("新增成功");
  457. this.open = false;
  458. this.getList();
  459. }
  460. });
  461. }
  462. }
  463. });
  464. },
  465. /** 删除按钮操作 */
  466. handleDelete(row) {
  467. const ids = row.id || this.ids;
  468. this.$confirm('是否确认删除中医档期业绩报表编号为"' + ids + '"的数据项?', "警告", {
  469. confirmButtonText: "确定",
  470. cancelButtonText: "取消",
  471. type: "warning"
  472. }).then(function() {
  473. return delTcmScheduleReport(ids);
  474. }).then(() => {
  475. this.getList();
  476. this.msgSuccess("删除成功");
  477. }).catch(function() {});
  478. },
  479. handleDetails(row){
  480. this.$router.push({path:'/schedule/report/add',query:{"scheduleId":row.scheduleId,"reportId":row.id}});
  481. },
  482. /** 导出按钮操作 */
  483. handleExport() {
  484. const queryParams = this.queryParams;
  485. this.$confirm('是否确认导出公司档期报表数据项?', "警告", {
  486. confirmButtonText: "确定",
  487. cancelButtonText: "取消",
  488. type: "warning"
  489. }).then(function() {
  490. return exportTcmScheduleReport(queryParams);
  491. }).then(response => {
  492. this.download(response.msg);
  493. }).catch(function() {});
  494. },
  495. getTreeselect() {
  496. var that=this;
  497. var param={companyId:this.companyId}
  498. treeselect(param).then((response) => {
  499. this.deptOptions = response.data;
  500. });
  501. },
  502. companyChange(val){
  503. //this.companyId=val;
  504. //console.log("qxj companyChange:"+val);
  505. var companyIdArr=this.companyIdArr;
  506. if(companyIdArr.length>0){
  507. this.companyId=companyIdArr[companyIdArr.length-1];
  508. }else{
  509. delete this.queryParams.deptId;
  510. this.companyId=this.companys[0].companyId;
  511. }
  512. this.getTreeselect();
  513. },
  514. currDeptChange(val){
  515. console.log(val)
  516. this.queryParams.deptId=val;
  517. this.getList();
  518. }
  519. }
  520. };
  521. </script>