| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- <template>
- <div class="container">
- <!-- 基本信息区域 -->
- <div class="top">
- <div class="top_tilte">
- <img src="@/assets/images/box-icon.png" />
- 基本信息
- </div>
- <div class="top_detail">
- <div class="detail_photo">
- <img
- class="img"
- src="https://img1.baidu.com/it/u=1398895526,1958525606&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800"
- />
- <div class="photo_icon">
- <el-icon size="20" color="#2493F1"><ArrowDownBold /></el-icon>
- </div>
- </div>
- <div class="detail_msg">
- <div>姓名:张晓晓</div>
- <div>性别:男</div>
- <div>编号:2216161</div>
- <div>部门:学生</div>
- </div>
- </div>
- </div>
- <!-- 考勤情况区域 -->
- <div class="bottom">
- <div class="bottom_title">
- <img src="@/assets/images/box-icon.png" />
- 考勤情况
- </div>
- <!-- 数据展示区域 -->
- <div class="bottom_msg">
- <div class="msg_change">
- <div
- class="change_box"
- :class="currentTimeRang === 0 ? 'active' : ''"
- @click="changeTimeRang(0)"
- >
- 本学期
- </div>
- <div
- class="change_box"
- :class="currentTimeRang === 1 ? 'active' : ''"
- @click="changeTimeRang(1)"
- >
- 本周
- </div>
- <div
- class="change_box"
- :class="currentTimeRang === 2 ? 'active' : ''"
- @click="changeTimeRang(2)"
- >
- 本月
- </div>
- </div>
- <div class="msg_detail">
- <div class="detail_box">
- <div class="box_num" ref="valueDom">{{ value }}</div>
- <div class="box_type">准时</div>
- </div>
- <div class="detail_box">
- <div class="box_num" ref="valueDom2">{{ value2 }}</div>
- <div class="box_type">请假</div>
- </div>
- <div class="detail_box">
- <div class="box_num" ref="valueDom3">{{ value3 }}</div>
- <div class="box_type">迟到</div>
- </div>
- <div class="detail_box">
- <div class="box_num" ref="valueDom4">{{ value4 }}</div>
- <div class="box_type">超时打卡</div>
- </div>
- <div class="detail_box">
- <div class="box_num" ref="valueDom5">{{ value5 }}</div>
- <div class="box_type">未打卡</div>
- </div>
- </div>
- </div>
- <!-- 图表展示区域 -->
- <div class="bottom_chart" ref="pieChart">123</div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { ref, onMounted } from "vue";
- import * as Echarts from "echarts";
- import { countUpNum } from "@/utils/countUpNum";
- // 引入用户画像相关的接口
- import { reqGetStudentAttendance } from "@/api/user/index";
- // 引入解密函数
- //@ts-ignore
- import { decryptDes } from "@/utils/des.ts";
- const value = ref(50);
- const value2 = ref(50);
- const value3 = ref(50);
- const value4 = ref(50);
- const value5 = ref(50);
- // DOM元素
- const valueDom = ref();
- const valueDom2 = ref();
- const valueDom3 = ref();
- const valueDom4 = ref();
- const valueDom5 = ref();
- let myPieChart: any;
- const pieChart = ref();
- // 切换考勤统计时间 0本学期 1本周 2本月
- const currentTimeRang = ref(0);
- const chartData = ref([
- { value: 5, name: "准时" },
- { value: 6, name: "请假" },
- { value: 3, name: "迟到" },
- { value: 2, name: "超时打卡" },
- { value: 1, name: "未打卡" },
- ]);
- onMounted(() => {
- // 获取学生历史出勤数据
- getStudentAttendance();
- myPieChart = Echarts.init(pieChart.value);
- initPieChart();
- getCountUpNum();
- });
- // 获取学生历史出勤数据
- const getStudentAttendance = async () => {
- const res = await reqGetStudentAttendance({
- userId: 7967,
- dateTime: 1,
- });
- // console.log(res);
- if ((res as any).code == 200) {
- const result = JSON.parse(decryptDes(res.data));
- console.log(result);
- }
- };
- const initPieChart = () => {
- const options = {
- title: {
- text: "总次数",
- left: "22%",
- top: "38%",
- textStyle: {
- fontSize: 14,
- color: "#D5E3EA",
- },
- subtext: "200",
- subtextStyle: {
- fontSize: 18,
- color: "#D5E3EA",
- align: "center",
- fontWeight: "bold",
- },
- itemGap: 15,
- },
- tooltip: {
- trigger: "item",
- },
- legend: {
- orient: "vertical",
- right: "4%",
- top: "center",
- itemWidth: 8,
- itemHeight: 8,
- itemGap: 25,
- textStyle: {
- padding: 8,
- color: "#fff",
- fontSize: 14,
- rich: {
- a: {
- fontSize: 16,
- fontWeight: "bold",
- align: "right",
- padding: [0, -100, 0, 0],
- },
- },
- },
- formatter: (params: any) => {
- const valueObj: any = chartData.value.find(
- (item) => item.name === params
- );
- return params + "{a|" + valueObj.value + "}";
- },
- },
- color: ["#50A4E1", "#FF85BE", "#FFC77D", "#93DE62", "#4AE8E8"],
- series: [
- {
- name: "考勤情况",
- type: "pie",
- center: ["28%", "50%"],
- radius: ["55%", "75%"],
- avoidLabelOverlap: false,
- label: {
- show: false,
- },
- itemStyle: {
- borderColor: "rgba(2, 27, 41, 0.1)",
- borderWidth: 5,
- },
- data: chartData.value,
- },
- ],
- };
- myPieChart.setOption(options);
- };
- // 考勤统计切换时间范围按钮回调
- const changeTimeRang = (value: number) => {
- if (currentTimeRang.value !== value) {
- if (value === 0) {
- currentTimeRang.value = 0;
- } else if (value === 1) {
- currentTimeRang.value = 1;
- } else if (value === 2) {
- currentTimeRang.value = 2;
- }
- }
- };
- // 让数字跳动
- const getCountUpNum = () => {
- countUpNum(valueDom.value, value.value);
- countUpNum(valueDom2.value, value2.value);
- countUpNum(valueDom3.value, value3.value);
- countUpNum(valueDom4.value, value4.value);
- countUpNum(valueDom5.value, value5.value);
- };
- </script>
- <style lang="scss" scoped>
- .container {
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- width: 500px;
- height: 834px;
- color: #fff;
- .top {
- padding: 17px 0 0 22px;
- height: 272px;
- background-image: url(@/assets/images/box-bg2.png);
- background-size: 100% 100%;
- .top_tilte {
- display: flex;
- align-items: center;
- font-size: 16px;
- font-weight: bold;
- img {
- margin-right: 12px;
- width: 24px;
- height: 24px;
- }
- }
- .top_detail {
- margin-top: 40px;
- display: flex;
- align-items: center;
- .detail_photo {
- position: relative;
- display: flex;
- justify-content: center;
- align-items: center;
- width: 122px;
- height: 122px;
- border-radius: 50%;
- background-color: #2493f1;
- img {
- width: 112px;
- height: 112px;
- border-radius: 50%;
- object-fit: cover;
- }
- .photo_icon {
- position: absolute;
- top: 45px;
- right: -14px;
- display: flex;
- justify-content: center;
- align-items: center;
- width: 34px;
- height: 34px;
- border-radius: 50%;
- background-color: #fff;
- }
- }
- .detail_msg {
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- margin-left: 63px;
- height: 122px;
- font-size: 14px;
- }
- }
- }
- .bottom {
- padding: 17px 54px 0 22px;
- height: 553px;
- background-image: url(@/assets/images/box-bg3.png);
- background-size: 100% 100%;
- .bottom_title {
- display: flex;
- align-items: center;
- font-size: 16px;
- font-weight: bold;
- img {
- margin-right: 12px;
- width: 24px;
- height: 24px;
- }
- }
- .bottom_msg {
- height: 262px;
- overflow: hidden;
- .msg_change {
- display: flex;
- justify-content: space-between;
- margin: 20px 0 33px 220px;
- padding: 2px;
- width: 200px;
- height: 32px;
- font-size: 14px;
- border-radius: 2px;
- border: 1px solid #9c9c9c;
- .change_box {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 61px;
- border-radius: 2px;
- background-color: rgba(114, 151, 179, 0.3);
- cursor: pointer;
- }
- .active {
- border: 1px solid #70b7fa;
- background-color: rgba(114, 151, 179, 1);
- }
- }
- .msg_detail {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- .detail_box {
- display: flex;
- flex-direction: column;
- align-items: center;
- width: 25%;
- height: 80px;
- .box_num {
- font-size: 28px;
- font-weight: bold;
- }
- .box_type {
- margin-top: 4px;
- font-size: 14px;
- }
- }
- }
- }
- .bottom_chart {
- height: 248px;
- }
- }
- }
- </style>
|