123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495 |
- <template>
- <div>
- <!-- B分排名 -->
- <van-nav-bar title="阶段排名(月、季度、年)" left-text="返回" @click-left="$route_back" left-arrow></van-nav-bar>
- <van-dropdown-menu>
- <van-dropdown-item :title="dateDropdownItemTitle" ref="dateDropdownItem">
- <div class="date-type__wrap">
- <div class="date-type__label" v-for="o in dateOption" :key="o.value" :class="{ active: dateType === o.value }" @click.stop="dateType = o.value">
- <span>{{ o.name }}</span>
- </div>
- </div>
- <van-picker v-if="dateType === 0" :columns="yearOption" @change="onYearChange" :default-index="10" item-height="40" />
- <van-datetime-picker v-show="dateType !== 0" v-model="date" type="year-month" :show-toolbar="false" item-height="40" :formatter="formatter" :filter="dateFilter" />
- <div class="date-picker__toolbar">
- <van-button class="reset-button button-border-none" block square color="rgba(38,162,255,0.2)" @click="onResetDate">重置</van-button>
- <van-button class="button-border-none" block square type="info" @click="onConfirmDate">确认</van-button>
- </div>
- </van-dropdown-item>
- <van-dropdown-item :title="deptDropdownItemTitle" ref="deptDropdownItem">
- <template slot="title">
- <Wxopendata type="departmentName" :openid="deptDropdownItemTitle"></Wxopendata>
- </template>
- <DeptSelectorDropdown @onConfirm="onConfirmDept" />
- </van-dropdown-item>
- <van-dropdown-item title="规则分类" ref="ruleDropdownItem"><RuleCategorySelDropdown @onConfirm="onConfirmRule" @onCancel="rule = null" /></van-dropdown-item>
- <van-dropdown-item :title="filterItemsTitle" ref="filterItems">
- <div class="filterItemsDiv">
- <div class="filterItemsTitle">人员</div>
- <div class="filterItemsContent">
- <div class="sub__item" v-for="(item, k) in position_arr" :key="k" @click="onselect(item, position_arr)" :class="{ selected: item.selected }">
- <span>{{ item.title }}</span>
- </div>
- </div>
- <div class="filterItemsTitle">排序</div>
- <div class="filterItemsContent">
- <div class="sub__item" v-for="(item, k) in sort_arr" :key="k" @click="onselect(item, sort_arr)" :class="{ selected: item.selected }">
- <span>{{ item.title }}</span>
- </div>
- </div>
- <div class="filterItemsTitle">积分类型</div>
- <div class="filterItemsContent">
- <div class="sub__item" v-for="(item, k) in types" :key="k" @click="onselect(item, types)" :class="{ selected: item.selected }">
- <span>{{ item.title }}</span>
- </div>
- </div>
- </div>
- <div class="date-picker__toolbar">
- <van-button class="reset-button button-border-none" block square color="rgba(38,162,255,0.2)" @click="onResetFilter">重置</van-button>
- <van-button class="button-border-none" block square type="info" @click="onConfirmFilter">确认</van-button>
- </div>
- </van-dropdown-item>
- </van-dropdown-menu>
- <div class="body_com has_header">
- <scroller ref="scroller" :on-refresh="onRefresh" :on-infinite="onInfinite">
- <van-cell v-for="(item, index) in data" :key="index" @click="openDetail(item)">
- <div slot="icon" class="rank-item__icon-wrap">
- <icon name="rank-first" v-if="item.rank == 1" class="rank-item__icon"></icon>
- <icon name="rank-second" v-if="item.rank == 2" class="rank-item__icon"></icon>
- <icon name="rank-third" v-if="item.rank == 3" class="rank-item__icon"></icon>
- <span v-if="item.rank > 3" class="rank-item__icon-label">{{ item.rank }}</span>
- </div>
- <div class="rank-item__name-wrap" slot="title">
- <userImage :img_url="item.employee_img_url" :user_name="item.employee_name" width="0.72rem" height="0.72rem" fontSize="0.2" style="margin-right: 0.1rem"></userImage>
- <span class="rank-item__name"><Wxopendata type="userName" :openid="item.employee_name"></Wxopendata></span>
- </div>
- <div class="rank-item__value" slot="right-icon">
- <span :class="{ negative: item.point < 0 }">{{ item.point }}</span>
- </div>
- </van-cell>
- <van-empty v-if="!hasData" description="暂没有排名数据..." />
- </scroller>
- </div>
- </div>
- </template>
- <script>
- import request from '@/utils/request'
- import DeptSelectorDropdown from '@/components/common/DeptSelectorDropdown' // 部门
- import RuleCategorySelDropdown from '@/components/common/RuleCategorySelDropdown' // 规则分类
- import userImage from '@/components/common/user_image'
- import Vue from 'vue'
- import { Empty, Picker, DropdownMenu, DropdownItem, DatetimePicker } from 'vant'
- import moment from 'moment'
- Vue.use(Empty).use(Picker).use(DropdownMenu).use(DropdownItem).use(DatetimePicker)
- export default {
- name: 'integral_rank',
- data () {
- const { month } = this.$route.query
- const dateNow = month ? moment(month).toDate() : new Date()
- const currYear = dateNow.getFullYear()
- return {
- page: 1,
- page_size: '20',
- sort: true,
- data: null,
- date: dateNow,
- dateType: 1,
- dateOption: [{ name: '年', value: 0 }, { name: '季度', value: 2 }, { name: '月', value: 1 }],
- departId: 0,
- year: currYear,
- loading: true,
- dateDropdownItemTitle: null,
- deptDropdownItemTitle: '部门',
- filterItemsTitle: '筛选',
- yearOption: this.getYearOption(currYear),
- mapDateDropdownItemTitle: { 0: '年', 1: '月', 2: '季度' },
- mapRankIconName: { 0: 'rank-first', 1: 'rank-second', 2: 'rank-third' },
- ruleId: null,
- position_arr: [{ title: '全部', code: 'all', selected: true }, { title: '管理者', code: 'manager', selected: false }, { title: '员工', code: 'employee', selected: false }],
- sort_arr: [{ title: '从高到低', code: 'DESC', selected: true }, { title: '从低到高', code: 'ASC', selected: false }],
- types: [{ title: 'B分', code: '3', selected: true }, { title: 'A分', code: '2', selected: false }],
- }
- },
- components: { DeptSelectorDropdown, userImage, RuleCategorySelDropdown },
- computed: {
- hasData () {
- // return this.loading || (Array.isArray(this.data) && this.data.length > 0)
- return (Array.isArray(this.data) && this.data.length > 0)
- }
- },
- watch: {
- dateType(val){
- let newData = new Date()
- if(val == 2){
- this.date = new Date(newData.getFullYear() + '-' + '01')
- }else if(val == 1){
- this.date = newData
- }
- },
- },
- methods: {
- // 打开明细列表
- openDetail (item) {
- console.log(item);
- var params = this.getParams()
- item.year = params.year// 年
- item.rule_id = params.rule// 分类
- item.quarter = params.quarter// 季度
- item.month = params.month
- item.pt_id=params.pt_id
- this.$router.push({ name: 'integralDetail', query: {item: JSON.stringify(item)}})
- },
- onConfirmRule (ruleIds) {
- ruleIds ? (this.ruleId = ruleIds) : (this.ruleId = null)
- this.$refs.ruleDropdownItem.toggle()
- this.$refs.scroller.triggerPullToRefresh()
- },
- sortNumber () {
- this.sort = !this.sort
- this.data.reverse()
- },
- getIconText (employeeName) {
- if (employeeName && employeeName.length > 2) {
- const len = employeeName.length
- return employeeName[len - 2] + employeeName[len - 1]
- }
- return employeeName
- },
- getYearOption (currYear) {
- const yearOption = []
- for (let i = currYear - 10; i <= currYear + 10; i++) {
- yearOption.push(i)
- }
- return yearOption
- },
- dateFilter (type, options) {
- if (type === 'month' && this.dateType === 2) {
- return options.filter(option => option < 5)
- }
- return options
- },
- formatter (type, val) {
- if (type === 'year') {
- return `${val}年`
- }
- return this.dateType === 2 ? `${val[1]}季度` : `${val}月`
- },
- getDateDropdownItemTitle () {
- if (this.dateType === 0) {
- return `${this.year}年`
- }
- return `${this.dateType === 1 ? this.date.getMonth() + 1 : this.date.getMonth() > 3 ? 1 : this.date.getMonth() + 1}${this.dateType === 1 ? '月' : '季度'}`
- },
- onYearChange (item, value) {
- this.year = value
- },
- onResetDate () {
- this.date = new Date()
- this.dateType = 1
- },
- onConfirmDate () {
- this.dateDropdownItemTitle = this.getDateDropdownItemTitle()
- this.$refs.dateDropdownItem.toggle()
- this.$refs.scroller.triggerPullToRefresh()
- },
- // 筛选项
- onResetFilter () {
- this.position_arr.forEach(element => {
- element.code == 'all' ? (element.selected = true) : (element.selected = false)
- })
- this.sort_arr.forEach(element => {
- element.selected = !element.selected
- })
- },
- onConfirmFilter () {
- this.$refs.filterItems.toggle()
- this.$refs.scroller.triggerPullToRefresh()
- },
- // 排序
- onselect (item, parent) {
- parent.forEach(element => {
- element.code == item.code ? (element.selected = true) : (element.selected = false)
- })
- },
- onConfirmDept (deptItem) {
- if (deptItem) {
- this.departId = deptItem.id
- this.deptDropdownItemTitle = deptItem.name
- } else {
- this.departId = 0
- this.deptDropdownItemTitle = '部门'
- }
- this.$refs.deptDropdownItem.toggle()
- this.$refs.scroller.triggerPullToRefresh()
- },
- getParams () {
- const pointTypeId = this.$store.getters.point_types.find(o => o.code === 'BF').id
- const params = { dept_id: this.departId, pt_id: pointTypeId, page: this.page, page_size: this.page_size }
- if (this.dateType === 0) {
- params.year = this.year
- } else if (this.dateType === 1) {
- params.month = moment(this.date).format('YYYY-MM')
- } else {
- params.quarter = this.date.getMonth() > 3 ? moment(this.date).format('YYYY') + '1' : moment(this.date).format('YYYYM')
- }
- this.ruleId ? (params.rule = this.ruleId) : (this.ruleId = null)
- this.position_arr.forEach(element => {
- if (element.selected) {
- params.position = element.code
- }
- })
- this.sort_arr.forEach(element => {
- if (element.selected) {
- params.sort = element.code
- }
- })
- this.types.forEach(element => {
- if (element.selected) {
- params.pt_id = element.code
- }
- })
- return params
- },
- // 加载
- showLoading () {
- this.$toast.loading({
- loadingType: 'spinner',
- message: '正在处理'
- })
- },
- get_list (done) {
- let self = this
- self.showLoading()
- const params = this.getParams()
- request('get', '/api/integral/statistics/ranking', params, 'v2').then(res => {
- done()
- if (res.data.code == 1) {
- self.$refs.scroller.finishInfinite(res.data.data.list.length != 20) // 停止上滚加载下一页,由于服务器端没有统一空数据和正常数据的格式,所以通过total字段来判定数据是否存在下一页
- const { list } = res.data.data
- if (self.page == 1) {
- self.data = list
- } else {
- self.data = self.data.concat(list)
- }
- } else {
- self.$refs.scroller.finishInfinite(true)
- }
- }).finally(() => {
- this.$toast.clear()
- })
- },
- onRefresh (done) {
- let self = this
- this.page = 1
- this.get_list(function () {
- self.list = []
- done()
- })
- },
- onInfinite (done) {
- this.page++
- this.get_list(done)
- }
- },
- mounted () {
- this.dateDropdownItemTitle = this.getDateDropdownItemTitle()
- this.$nextTick(() => {
- this.$refs.scroller.finishInfinite(false)
- })
- }
- }
- </script>
- <style scoped lang="less">
- .body_com {
- height: calc(100% - 1.92rem);
- position: relative;
- }
- /deep/ .body_com .van-hairline--top-bottom:after {
- border: none;
- }
- /deep/ .body_com .van-hairline-unset--top-bottom:after {
- border: none;
- }
- .date-type__wrap {
- display: flex;
- padding: 0.24rem 0.32rem;
- flex-direction: row;
- justify-content: center;
- & .date-type__label {
- display: flex;
- width: 1.4rem;
- height: 0.52rem;
- font-size: 0.3rem;
- color: #fff;
- background: #26a2ff;
- border-top: 0.02rem solid #26a2ff;
- border-bottom: 0.02rem solid #26a2ff;
- border-left: 0.02rem solid #fff;
- align-items: center;
- justify-content: center;
- transition: color, background-color 100ms;
- &.active {
- color: #26a2ff;
- background: #fff;
- &:first-child {
- border-left: 0.02rem solid #26a2ff;
- }
- }
- &:first-child {
- border-radius: 0.08rem 0 0 0.08rem;
- }
- &:last-child {
- border-right: 0.02rem solid #26a2ff;
- border-radius: 0 0.08rem 0.08rem 0;
- }
- }
- }
- .date-picker__toolbar {
- display: flex;
- flex-direction: row;
- & .reset-button {
- color: #26a2ff !important;
- }
- & .button-border-none {
- border: transparent !important;
- }
- }
- .dropdown-menu__item {
- position: relative;
- display: flex;
- flex: 1;
- min-width: 0;
- font-size: 0.3rem;
- color: #323233;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- & > span {
- position: relative;
- box-sizing: border-box;
- max-width: 100%;
- padding: 0 0.16rem;
- color: #323233;
- font-size: 0.3rem;
- line-height: 0.36rem;
- &:after {
- position: absolute;
- top: 50%;
- right: -0.08rem;
- margin-top: -0.1rem;
- border: 0.06rem solid;
- border-color: transparent transparent currentColor currentColor;
- transform: rotate(-45deg);
- opacity: 0.8;
- content: '';
- }
- &.asc-order:after {
- margin-top: -0.02rem;
- transform: rotate(135deg);
- }
- }
- }
- .rank-item__icon-wrap {
- display: flex;
- padding-right: 0.32rem;
- width: 0.64rem;
- align-items: center;
- justify-content: center;
- & .rank-item__icon {
- width: 0.64rem;
- }
- & .rank-item__icon-label {
- position: relative;
- }
- }
- .rank-item__name-wrap {
- display: flex;
- width: 100%;
- height: 100%;
- align-items: center;
- & .rank-item__name-icon {
- position: relative;
- display: flex;
- width: 0.96rem;
- height: 0.96rem;
- font-size: 0.3rem;
- color: #fff;
- background: #26a2ff;
- align-items: center;
- justify-content: center;
- border-radius: 100%;
- }
- & .rank-item__name {
- padding-left: 0.24rem;
- }
- }
- & /deep/ .rank-item__value {
- display: flex;
- color: #26a2ff;
- align-items: center;
- text-align: right;
- & .negative {
- color: #ff2d55;
- }
- }
- .filterItemsDiv {
- & .filterItemsTitle {
- padding: 0 0.13rem;
- color: #333;
- font-size: 0.3rem;
- }
- & .filterItemsContent {
- display: flex;
- padding-bottom: 0.24rem;
- & .sub__item {
- display: flex;
- margin: 0.24rem 0.13rem 0 0.13rem;
- width: 1.52rem;
- height: 0.72rem;
- background: #f5f7fa;
- border-radius: 0.04rem;
- align-items: center;
- justify-content: center;
- touch-action: none;
- &.selected {
- color: #26a2ff;
- background: #26a2ff33;
- }
- & span {
- font-size: 0.28rem;
- }
- }
- }
- }
- </style>
|