report.vue 17 KB

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