salesStatistics.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. <script setup>
  2. import {getSellerGroupStatisticsList,getSellerStatisticsList} from '@/api/financialStatistics'
  3. import {getSellerGroupList,getSellerTeamList} from '@/api/crm'
  4. import {downloadByFlow} from '@/utils/common-methods'
  5. const moment = inject('$moment')
  6. const sortFiledMap = new Map([['invoice_amount',1],['group_rate',2],['seller_rate',3]])
  7. const customerTypeArray=[{label:'全部',value:0},{label:'新客户',value:1},{label:'老客户',value:2}]
  8. const dateButtonData=[{text:'近1周',tabId:1,type:'week',diff:1},{text:'近1月',tabId:2,type:'month',diff:1},
  9. {text:'近2月',tabId:3,type:'month',diff:2},{text:'近3月',tabId:4,type:'month',diff:3},{text:'今年以来',tabId:5,type:'year',diff:1}]
  10. // let groupList=ref([])
  11. let sellerSellerTeamList=ref([])
  12. const tabType=ref(1)
  13. const statisticsData=reactive({
  14. tableData:[],
  15. total:0
  16. })
  17. // 搜索参数
  18. const searchParams=reactive({
  19. current:1,
  20. page_size:10,
  21. // group_id:'',
  22. seller_ids:'',
  23. start_date:'',
  24. end_date:'',
  25. // 排序字段: 1-开票金额; 2-组别占比
  26. sort_field:'',
  27. // 排序方式: 1-正序; 2-倒序
  28. sort_type:'',
  29. // 是否导出:0-否;1-是
  30. is_export:0,
  31. // 销售类型 1-ficc销售 2-权益销售
  32. seller_type:1,
  33. company_type:0,
  34. show_resign:false
  35. })
  36. // 搜索参数-创建时间数组
  37. const createtime=ref(null)
  38. // 日期按钮选项
  39. const currentTabId=ref(0)
  40. watch(createtime,(newVal)=>{
  41. if(newVal){
  42. searchParams.start_date=newVal[0]
  43. searchParams.end_date=newVal[1]
  44. }else{
  45. searchParams.start_date=''
  46. searchParams.end_date=''
  47. }
  48. searchStatistics()
  49. })
  50. // 销售类型缓存 为了减少请求次数
  51. // let sellerTypeCache=0
  52. const changeTab=(tab)=>{
  53. if(tabType.value==tab) return
  54. tabType.value=tab
  55. // if(tab==2 && sellerTypeCache!=searchParams.seller_type){
  56. // getSellerGroup()
  57. getSellerListFun()
  58. // }
  59. searchParams.current=1
  60. searchParams.page_size=10
  61. // searchParams.group_id=''
  62. searchParams.seller_ids=''
  63. searchParams.sort_field=''
  64. searchParams.sort_type=''
  65. searchParams.company_type=0
  66. searchParams.show_resign=false
  67. currentTabId.value=0
  68. if(createtime.value===null){
  69. statisticsList()
  70. }else{
  71. // 监听了createtime,createtime变化就会发起请求,避免发起两次请求
  72. createtime.value=null
  73. }
  74. }
  75. const sellerChange=(value)=>{
  76. console.log(value);
  77. searchParams.seller_ids=(value&&value.length)?value.join(','):''
  78. statisticsList()
  79. }
  80. // 获取列表
  81. const statisticsList=()=>{
  82. if(tabType.value==1){
  83. // 销售组排名 - 无分页
  84. getSellerGroupStatisticsList(searchParams).then(res=>{
  85. statisticsData.tableData = res.data || []
  86. statisticsData.total = 0
  87. })
  88. }else if(tabType.value==2){
  89. // 销售排名
  90. getSellerStatisticsList(searchParams).then(res=>{
  91. statisticsData.tableData = res.data.list || []
  92. statisticsData.total = res.data.page.total || 0
  93. })
  94. }
  95. }
  96. // 获取销售组别
  97. // const getSellerGroup=()=>{
  98. // sellerTypeCache=searchParams.seller_type
  99. // getSellerGroupList({seller_type:searchParams.seller_type}).then(res=>{
  100. // groupList.value=res.data || []
  101. // })
  102. // }
  103. //获取销售列表
  104. const getSellerListFun=()=>{
  105. getSellerTeamList().then(res=>{
  106. sellerSellerTeamList.value = res.data.all_list || []
  107. })
  108. }
  109. // 切换销售类型
  110. // const changeSellerType=()=>{
  111. // if(tabType.value==2&&sellerTypeCache!=searchParams.seller_type){
  112. // searchParams.group_id=''
  113. // getSellerGroup()
  114. // }
  115. // searchStatistics()
  116. // }
  117. // 日期选项改变
  118. const changeDateType=()=>{
  119. let currentTab = dateButtonData.find(it => it.tabId == currentTabId.value)
  120. if(!currentTab) return
  121. let {type,diff} = currentTab
  122. let startOfType=type
  123. if(type=='week'){
  124. startOfType='isoWeek'
  125. }
  126. createtime.value=[moment().startOf(startOfType).subtract((diff-1), type+'s').format('YYYY-MM-DD'),
  127. moment().format('YYYY-MM-DD')]
  128. }
  129. const searchStatistics=()=>{
  130. searchParams.current = 1
  131. statisticsList()
  132. }
  133. // 切换每页的数量
  134. const changePageSize=(pageSize)=>{
  135. searchParams.page_size = pageSize
  136. statisticsList()
  137. }
  138. const changePageNo = (pageNo)=>{
  139. searchParams.current = pageNo
  140. statisticsList()
  141. }
  142. // 列表排序发生改变
  143. const sortChange=({order,prop})=>{
  144. searchParams.sort_field=sortFiledMap.get(prop)
  145. searchParams.sort_type=order == 'ascending'?1:2
  146. statisticsList()
  147. }
  148. // 导出
  149. const statisticeExport=()=>{
  150. if(tabType.value == 1){
  151. getSellerGroupStatisticsList({...searchParams,is_export:1}).then(res=>{
  152. downloadByFlow(res,'xlsx',`销售统计-销售组排名列表`)
  153. })
  154. }else if(tabType.value == 2){
  155. getSellerStatisticsList({...searchParams,is_export:1}).then(res=>{
  156. downloadByFlow(res,'xlsx',`销售统计-销售排名列表`)
  157. })
  158. }
  159. }
  160. // ------------------------------------------------
  161. statisticsList()
  162. </script>
  163. <template>
  164. <div id="sales-statistics-container" class="sales-statistics-container">
  165. <div class="statistics-tabs-zone">
  166. <el-button size="large" class="tab-button element-common-button" :class="tabType==1?'actice-tab':''"
  167. style="border-radius: 4px 0 0 4px;" @click="changeTab(1)">销售组排名</el-button>
  168. <el-button size="large" class="tab-button element-common-button" :class="tabType==2?'actice-tab':''"
  169. style="border-radius: 0 4px 4px 0;margin-left: 0;" @click="changeTab(2)">销售排名</el-button>
  170. </div>
  171. <div class="statistics-top-zone">
  172. <div class="statistics-search-zone">
  173. <el-select v-model="searchParams.seller_type" placeholder="请选择销售类型"
  174. @change="searchStatistics" class="statistics-search-item" v-show="tabType==1">
  175. <el-option label="FICC销售" :value="1"></el-option>
  176. <el-option label="权益销售" :value="2"></el-option>
  177. </el-select>
  178. <!-- <el-select v-model="searchParams.group_id" placeholder="请选择销售组别" class="statistics-search-item"
  179. @change="searchStatistics" v-show="tabType==2" clearable >
  180. <el-option :label="item.group_name" :value="item.group_id" v-for="item in groupList"></el-option>
  181. </el-select> -->
  182. <el-cascader :options="sellerSellerTeamList" style="width: 240px;margin:0 30px 8px 0;" filterable collapse-tags-tooltip
  183. @change="sellerChange" placeholder="请选择销售" clearable collapse-tags :show-all-levels="false"
  184. :props="{multiple:true,label:'seller_name',value:'seller_id',children:'child',emitPath:false}" key="seller"
  185. v-if="tabType==2">
  186. </el-cascader>
  187. <el-checkbox v-model="searchParams.show_resign" style="margin: 0 30px 8px 0;"
  188. v-show="tabType==2" @change="searchStatistics">显示离职销售</el-checkbox>
  189. <el-radio-group v-model="searchParams.company_type" size="large" @change="searchStatistics"
  190. style="margin: 0 30px 8px 0;">
  191. <el-radio-button v-for="item in customerTypeArray" :key="item.value" class="dimension-radio"
  192. :label="item.value" >{{ item.label }}</el-radio-button>
  193. </el-radio-group>
  194. <div class="date-box">
  195. <el-date-picker v-model="createtime" type="daterange" @change="currentTabId=0"
  196. value-format="YYYY-MM-DD" style="max-width:240px;margin-right: 30px"
  197. start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
  198. <el-radio-group v-model="currentTabId" size="large" @change="changeDateType">
  199. <el-radio-button v-for="item in dateButtonData" :key="item.tabId" class="dimension-radio"
  200. :label="item.tabId" >{{ item.text }}</el-radio-button>
  201. </el-radio-group>
  202. </div>
  203. </div>
  204. <div class="statistice-buttons-zone">
  205. <el-button @click="statisticeExport" class="element-common-button" size="large">导出</el-button>
  206. </div>
  207. </div>
  208. <div class="statistics-table-zone" >
  209. <el-table :data="statisticsData.tableData" border
  210. max-height="600" @sort-change="sortChange" size='large'>
  211. <el-table-column label="排名" align="center">
  212. <template #default="{$index}">
  213. {{ searchParams.page_size*(searchParams.current-1)+$index+1}}
  214. </template>
  215. </el-table-column>
  216. <el-table-column label="销售员" prop="seller_name" align="center" v-if="tabType==2"></el-table-column>
  217. <el-table-column label="销售组别" prop="group_name" align="center"></el-table-column>
  218. <el-table-column label="收入金额(元)" prop="invoice_amount" align="center" sortable="custom" >
  219. <template #header>
  220. <el-tooltip content="收入金额为开票金额换算后的人民币金额" placement="top">
  221. <span style="display: inline-flex;align-items: center;">收入金额(元)
  222. <svg-Icon name="svgIcon-financial-info" size="18" color="#C0C4CC" style="margin-left: 5px;color: white;" />
  223. </span>
  224. </el-tooltip>
  225. </template>
  226. </el-table-column>
  227. <el-table-column label="小组占比" prop="group_rate" align="center" sortable="custom">
  228. <template #default="{row}">
  229. {{ row.group_rate+'%' }}
  230. </template>
  231. </el-table-column>
  232. <el-table-column label="全员占比" prop="seller_rate" align="center" sortable="custom" v-if="tabType==2">
  233. <template #default="{row}">
  234. {{ (row.seller_rate || '0.00')+'%' }}
  235. </template>
  236. </el-table-column>
  237. <template #empty>
  238. <div class="table-no-data">
  239. <img src="@/assets/img/icon/empty-data.png" />
  240. <span>暂无数据</span>
  241. </div>
  242. </template>
  243. </el-table>
  244. <!-- 分页 -->
  245. <m-page :pageSize="searchParams.page_size" :page_no="searchParams.current"
  246. style="display: flex;justify-content: flex-end;margin-top: 20px;"
  247. :total="statisticsData.total" @handleCurrentChange="changePageNo" @handleSizeChange="changePageSize"/>
  248. </div>
  249. </div>
  250. </template>
  251. <style lang="scss" scoped>
  252. #sales-statistics-container{
  253. min-height: 100%;
  254. .statistics-tabs-zone{
  255. margin-bottom: 26px;
  256. .tab-button{
  257. color: $themeColor;
  258. border: 1px solid $themeColor;
  259. width: 130px;
  260. background-color: white;
  261. }
  262. .actice-tab{
  263. color: white;
  264. background-color: $themeColor;
  265. }
  266. }
  267. .statistics-top-zone{
  268. display: flex;
  269. justify-content: space-between;
  270. margin-bottom: 20px;
  271. .statistics-search-zone{
  272. display: flex;
  273. align-items: center;
  274. flex-wrap: wrap;
  275. // margin-right: 30px;
  276. .statistics-search-item{
  277. width: 200px;
  278. margin-bottom: 8px;
  279. margin-right: 30px;
  280. }
  281. .date-box{
  282. display: flex;
  283. align-items: center;
  284. margin: 0 30px 8px 0;
  285. }
  286. }
  287. }
  288. }
  289. </style>
  290. <style lang="scss">
  291. #sales-statistics-container{
  292. .el-radio-group{
  293. flex-wrap: nowrap;
  294. }
  295. .dimension-radio{
  296. span{
  297. display: inline-block;
  298. color: $hitTextColorTwo;
  299. padding: 12px 12px;
  300. }
  301. }
  302. .is-active{
  303. span{
  304. color:white
  305. }
  306. }
  307. }
  308. </style>