| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- <template>
- <div>
- <div
- class="mt-[30px] mb-[20px] bg-[#fff] rounded-[10px] p-[15px] flex justify-between"
- >
- <div
- v-for="item in tabList"
- :key="item.value"
- @click="
- () => {
- searchForm.type = item.value;
- activeTab = item.value;
- refresh();
- }
- "
- class="px-[20px] py-[10px] rounded-[5px] cursor-pointer transition-all duration-300"
- :class="{ 'bg-[#4466ee] text-white': searchForm.type == item.value }"
- >
- <span class="text-[16px] flex items-center"
- ><sa-icon :icon="item.icon" class="text-[16px] mr-[5px]" />{{
- item.label
- }}</span
- >
- </div>
- </div>
- <div>
- <div class="mb-[15px]">
- <sa-icon
- :icon="tabList.find((item) => item.value === activeTab).icon"
- class="text-[25px] mr-[5px]"
- />
- <span class="text-[25px] font-bold"
- >{{
- tabList.find((item) => item.value === activeTab).label
- }}对比</span
- >
- </div>
- </div>
- <div class="grid grid-cols-3 gap-[15px]">
- <a-card
- class="text-center rounded-[10px] hover:translate-y-[-5px] transition-all duration-300 cursor-pointer p-[10px] border-none"
- >
- <div class="text-[#6c757d] text-[18px] font-bold">
- {{ dictOptions[searchForm.type] }}下单量
- </div>
- <a-statistic
- class="my-[5px]"
- :value="orderNum || 0"
- :value-from="0"
- animation
- show-group-separator
- value-style="color: #4361ee; font-size: 44px; font-weight: bold; line-height: 1.2;"
- />
- <div class="text-[15px] font-bold">
- <a-statistic
- :value="comparison.changes.orderChange.percentageText"
- :precision="2"
- :value-from="0"
- :start="start"
- animation
- value-style="color: #09d6a1; font-size: 15px; font-weight: bold; line-height: 1.2;"
- >
- <template #prefix>
- <icon-arrow-rise
- v-if="comparison.changes.orderChange.trend === 'up'"
- />
- <icon-arrow-fall v-else />
- </template>
- <template #suffix
- >% {{ comparison.changes.orderChange.label }}</template
- >
- </a-statistic>
- </div>
- </a-card>
- <a-card
- class="text-center rounded-[10px] hover:translate-y-[-5px] transition-all duration-300 cursor-pointer p-[10px] border-none"
- >
- <div class="text-[#6c757d] text-[18px] font-bold">
- {{ dictOptions[searchForm.type] }}支付量
- </div>
- <a-statistic
- class="my-[5px]"
- :value="successNum || 0"
- :value-from="0"
- animation
- show-group-separator
- value-style="color: #4361ee; font-size: 44px; font-weight: bold; line-height: 1.2;"
- />
- <div class="text-[15px] font-bold">
- <a-statistic
- :value="comparison.changes.payChange.percentageText"
- :precision="2"
- :value-from="0"
- :start="start"
- animation
- value-style="color: #09d6a1; font-size: 15px; font-weight: bold; line-height: 1.2;"
- >
- <template #prefix>
- <icon-arrow-rise
- v-if="comparison.changes.orderChange.trend === 'up'"
- />
- <icon-arrow-fall v-else />
- </template>
- <template #suffix
- >% {{ comparison.changes.payChange.label }}</template
- >
- </a-statistic>
- </div>
- </a-card>
- <a-card
- class="text-center rounded-[10px] hover:translate-y-[-5px] transition-all duration-300 cursor-pointer p-[10px] border-none"
- >
- <div class="text-[#6c757d] text-[18px] font-bold">
- {{ dictOptions[searchForm.type] }}支付成功率
- </div>
- <a-statistic
- class="my-[5px]"
- :value="paySuccessRate * 100 || 0"
- :value-from="0"
- animation
- show-group-separator
- value-style="color: #4361ee; font-size: 44px; font-weight: bold; line-height: 1.2;"
- >
- <template #suffix>%</template>
- </a-statistic>
- <div class="text-[15px] font-bold">
- <a-statistic
- :value="comparison.changes.rateChange.percentageText"
- :precision="2"
- :value-from="0"
- :start="start"
- animation
- value-style="color: #f53f3f; font-size: 15px; font-weight: bold; line-height: 1.2;"
- >
- <template #prefix>
- <icon-arrow-rise
- v-if="comparison.changes.orderChange.trend === 'up'"
- />
- <icon-arrow-fall v-else />
- </template>
- <template #suffix
- >% {{ comparison.changes.orderChange.label }}</template
- >
- </a-statistic>
- </div>
- </a-card>
- </div>
- <div class="mt-[24px] gap-[15px] flex">
- <a-card class="w-[70%]" title="支付成功率对比">
- <sa-chart :option="lineChartOption" height="300px" />
- </a-card>
- <a-card class="w-[30%]" title="支付渠道下单比例">
- <div class="text-center text-[16px] text-[#6c757d]">
- 待确认开发中...
- </div>
- <!-- <sa-chart :option="lineChartOption" height="300px" /> -->
- </a-card>
- </div>
- <a-card title="详细数据" class="mt-[24px]">
- <sa-table
- ref="crudRef"
- :searchForm="searchForm"
- :columns="columns"
- :options="options"
- />
- </a-card>
- </div>
- </template>
- <script setup>
- import { onMounted, reactive, ref, watch, nextTick } from "vue";
- import SaIcon from "@/components/sa-icon/index.vue";
- import SaChart from "@/components/sa-chart/index.vue";
- import api from "../../api/gameLog/analyse";
- const crudRef = ref();
- const orderNum = ref(0);
- const successNum = ref(0);
- const paySuccessRate = ref(0);
- const dictOptions = ref({
- day: "今日",
- week: "本周",
- month: "本月",
- });
- const searchForm = ref({
- type: "day",
- });
- const lineChartOption = ref({});
- const chartOption = ref({});
- const comparison = ref({
- changes: {
- orderChange: {
- percentage: 0,
- trend: "up",
- value: 0,
- percentageText: "",
- icon: "icon-arrow-rise",
- label: "",
- },
- payChange: {
- percentage: 0,
- trend: "up",
- value: 0,
- percentageText: "",
- icon: "icon-arrow-rise",
- label: "",
- },
- rateChange: {
- percentage: 0,
- trend: "up",
- percentageText: "",
- value: 0,
- icon: "icon-arrow-rise",
- label: "",
- },
- },
- });
- const options = reactive({
- api: api.getPaySuccessRate,
- pk: "time",
- showSort: false,
- operationColumn: false,
- showSearch: false,
- pageSimple: true,
- pageLayout: "normal", // 改为普通布局,避免固定高度问题
- height: "auto", // 自动高度
- });
- const columns = reactive([
- {
- title: "时段",
- dataIndex: "time",
- width: 100,
- },
- {
- title: "今日下单量",
- dataIndex: "todayOrderNum",
- },
- {
- title: "今日支付量",
- dataIndex: "todayPayNum",
- },
- {
- title: "今日成功率",
- dataIndex: "todayPaySuccessRate",
- },
- {
- title: "昨日下单量",
- dataIndex: "yesterdayOrderNum",
- },
- {
- title: "昨日支付量",
- dataIndex: "yesterdayPayNum",
- },
- {
- title: "昨日成功率",
- dataIndex: "yesterdayPaySuccessRate",
- },
- {
- title: "成功率变化",
- dataIndex: "successRateChange",
- },
- ]);
- const tabList = ref([
- {
- label: "今日 vs 昨日",
- value: "day",
- icon: "IconSun",
- },
- {
- label: "本周 vs 上周",
- value: "week",
- icon: "IconCalendar",
- },
- // {
- // label: "本月 vs 上月",
- // value: "month",
- // icon: "IconComputer",
- // },
- ]);
- const activeTab = ref("day");
- // 请求支付成功率
- const getPaySuccessRate = async () => {
- const res = await api.getPaySuccessRate({
- type: searchForm.value.type,
- });
- let data = res.data;
- orderNum.value = data.orderNum;
- successNum.value = data.successNum;
- paySuccessRate.value = data.paySuccessRate;
- chartOption.value = {
- legend: {
- data: ["今日支付成功率", "昨日支付成功率"],
- itemGap: 5,
- },
- grid: {
- left: "1%",
- right: "10%",
- containLabel: true,
- },
- xAxis: {
- type: "category",
- data: data.xAxisData,
- },
- yAxis: {
- type: "value",
- },
- series: [
- {
- name: "今日支付成功率",
- type: "bar",
- data: data.PaySuccessRateArr,
- },
- {
- name: "昨日支付成功率",
- type: "bar",
- data: data.OldPaySuccessRate,
- },
- ],
- tooltip: {
- trigger: "axis",
- },
- };
- lineChartOption.value = {
- tooltip: {
- trigger: "axis",
- axisPointer: {
- type: "cross",
- label: {
- backgroundColor: "#6a7985",
- },
- },
- },
- legend: {
- data: ["今日", "昨日"],
- itemGap: 5,
- },
- toolbox: {
- feature: {
- saveAsImage: {},
- },
- },
- xAxis: [
- {
- type: "category",
- boundaryGap: false,
- data: data.xAxisData,
- },
- ],
- yAxis: [
- {
- type: "value",
- },
- ],
- series: [
- {
- name: "今日",
- type: "line",
- areaStyle: {},
- emphasis: {
- focus: "series",
- },
- data: data.PaySuccessRateArr,
- },
- {
- name: "昨日",
- type: "line",
- areaStyle: {},
- emphasis: {
- focus: "series",
- },
- data: data.OldPaySuccessRateArr,
- },
- ],
- };
- };
- // SaTable 数据请求
- const refresh = async () => {
- await getPaySuccessRate();
- // 延迟刷新表格,确保数据已经更新
- await nextTick();
- crudRef.value?.refresh();
- };
- onMounted(() => {
- refresh();
- });
- </script>
- <style scoped></style>
|