|
@@ -10,56 +10,113 @@
|
|
|
</template>
|
|
|
</v-tooltip>
|
|
|
</div>
|
|
|
- <div class="overview-item-value my-3 cursor-pointer">{{ overviewData[val.key] }}</div>
|
|
|
- <div class="font-size-14">
|
|
|
- 环比
|
|
|
- <span class="color-error">{{ typeof val.ratio === 'number' ? val.ratio : overviewData[val.ratio] }}% ↑</span>
|
|
|
- </div>
|
|
|
+ <div class="overview-item-value my-3 cursor-pointer" @click.stop="handleDetails(val, i)">{{ val.value }}</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
+
|
|
|
+ <CtDialog :visible="show" :widthType="1" titleClass="text-h6" :footer="false" :title="title" @close="handleClose">
|
|
|
+ <CtTable
|
|
|
+ :items="data"
|
|
|
+ :headers="headersList[current]"
|
|
|
+ :loading="false"
|
|
|
+ :elevation="0"
|
|
|
+ :isTools="false"
|
|
|
+ :showPage="true"
|
|
|
+ :total="total"
|
|
|
+ :page-info="queryParams"
|
|
|
+ itemKey="id"
|
|
|
+ @pageHandleChange="handleChangePage"
|
|
|
+ >
|
|
|
+ </CtTable>
|
|
|
+ </CtDialog>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
defineOptions({ name: 'overview-page'})
|
|
|
-import { ref } from 'vue'
|
|
|
-// import { getRecentConversations } from '@/api/recruit/enterprise/statistics'
|
|
|
-// const props = defineProps({
|
|
|
-// query: Object
|
|
|
-// })
|
|
|
+import { reactive, ref, watch, onMounted } from 'vue'
|
|
|
+import { getJobBrowseNumPage, getJobCvNewPage, getJobCvLookPage, getInterviewWaitPage, getInterviewCompletePage } from '@/api/recruit/enterprise/statistics'
|
|
|
+import headersList from '@/utils/statisticsHeaders'
|
|
|
+import { dealDictArrayData, dealDictObjData } from '@/utils/position'
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ query: Object
|
|
|
+})
|
|
|
|
|
|
-const overviewData = ref({
|
|
|
- position: 0,
|
|
|
- resume: 0,
|
|
|
- viewResume: 0,
|
|
|
- interview: 0,
|
|
|
- interviewFinish: 0
|
|
|
+const queryParams = reactive({
|
|
|
+ pageNo: 1,
|
|
|
+ pageSize: 10
|
|
|
})
|
|
|
+const show = ref(false)
|
|
|
+const total = ref(0)
|
|
|
+const current = ref(0)
|
|
|
+const title = ref('')
|
|
|
+const data = ref([])
|
|
|
// 数据概况
|
|
|
const overview = ref([
|
|
|
- { title: '职位浏览量', key: 'position', ratio: 0, desc: '指全部职位被候选人查看的人数总和' },
|
|
|
- { title: '收到简历量', key: 'resume', ratio: 0, desc: '指全部职位收到简历的总数' },
|
|
|
- { title: '查看收到简历', key: 'viewResume', ratio: 0, desc: '指查看候选人主动发送的简历数量' },
|
|
|
- { title: '面试-已邀约', key: 'interview', ratio: 0, desc: '已邀约的面试人数' },
|
|
|
- { title: '面试-已完成', key: 'interviewFinish', ratio: 0, desc: '已完成面试的人数' },
|
|
|
+ { title: '职位浏览量', value: 0, desc: '指全部职位被候选人查看的人数总和', items: [], api: getJobBrowseNumPage, deal: true },
|
|
|
+ { title: '收到的简历', value: 0, desc: '指全部职位收到简历的总数', items: [], api: getJobCvNewPage, isDeal: true },
|
|
|
+ { title: '已查看简历', value: 0, desc: '指查看候选人主动发送的简历数量', items: [], api: getJobCvLookPage },
|
|
|
+ { title: '已邀面试', value: 0, desc: '已邀约的面试人数', items: [], api: getInterviewWaitPage },
|
|
|
+ { title: '面试完成', value: 0, desc: '已完成面试的人数', items: [], api: getInterviewCompletePage }
|
|
|
])
|
|
|
|
|
|
-// 主动联系我的、我主动联系的人
|
|
|
-// const accountInfo = localStorage.getItem('accountInfo') ? JSON.parse(localStorage.getItem('accountInfo')) : {}
|
|
|
-// const getRecent = async () => {
|
|
|
-// if (!accountInfo || !accountInfo.userId) return
|
|
|
-// const data = await getRecentConversations({ userId: accountInfo.userId, ...props.query })
|
|
|
-// overviewData.value = Object.assign(overviewData.value, data)
|
|
|
-// }
|
|
|
-// getRecent()
|
|
|
+// 钻取
|
|
|
+const handleDetails = (val, index) => {
|
|
|
+ show.value = true
|
|
|
+ current.value = index
|
|
|
+ total.value = val.value
|
|
|
+ title.value = val.title + '明细'
|
|
|
+ data.value = val.items
|
|
|
+}
|
|
|
+
|
|
|
+const handleClose = () => {
|
|
|
+ show.value = false
|
|
|
+ total.value = 0
|
|
|
+ current.value = 0
|
|
|
+ title.value = ''
|
|
|
+ data.value = []
|
|
|
+ queryParams.pageNo = 1
|
|
|
+}
|
|
|
+
|
|
|
+const handleChangePage = (val) => {
|
|
|
+ queryParams.pageNo = val
|
|
|
+ getData(current.value)
|
|
|
+}
|
|
|
+
|
|
|
+// 统计数值
|
|
|
+const getData = async (index) => {
|
|
|
+ if (index !== null && index !== undefined) {
|
|
|
+ const obj = overview.value[index]
|
|
|
+ const res = await obj.api({ ...props.query, ...queryParams })
|
|
|
+ total.value = res.total
|
|
|
+ data.value = obj.deal ? dealDictArrayData([], res.list) : obj.isDeal ? res.list.map(e => {
|
|
|
+ e.job = dealDictObjData({}, e.job)
|
|
|
+ return e
|
|
|
+ }) : res.list
|
|
|
+ return
|
|
|
+ }
|
|
|
+ overview.value.forEach(async (item) => {
|
|
|
+ const { list, total } = await item.api({ ...props.query, ...queryParams })
|
|
|
+ item.value = total
|
|
|
+ item.items = item.deal ? dealDictArrayData([], list) : item.isDeal ? list.map(e => {
|
|
|
+ e.job = dealDictObjData({}, e.job)
|
|
|
+ return e
|
|
|
+ }) : list
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ getData()
|
|
|
+})
|
|
|
|
|
|
-// watch(
|
|
|
-// () => props.query,
|
|
|
-// (val) => {
|
|
|
-// if (val) getRecent()
|
|
|
-// },
|
|
|
-// { deep: true }
|
|
|
-// )
|
|
|
+watch(
|
|
|
+ () => props.query,
|
|
|
+ (val) => {
|
|
|
+ if (val) getData()
|
|
|
+ },
|
|
|
+ { deep: true }
|
|
|
+)
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
@@ -74,7 +131,7 @@ const overview = ref([
|
|
|
max-width: calc((100% - 48px) / 5);
|
|
|
// min-width: 200px;
|
|
|
margin: 0 12px 12px 0;
|
|
|
- height: 175px;
|
|
|
+ height: 140px;
|
|
|
border-radius: 12px;
|
|
|
overflow: hidden;
|
|
|
transition: all .2s linear;
|