4 커밋 292f1788e5 ... 2bff6d6005

작성자 SHA1 메시지 날짜
  maa3606 2bff6d6005 Merge branch 'kevin' 2 년 전
  maa3520 ac1aacb5d4 完成亂數機率分布 2 년 전
  maa3520 ec7e4b8e13 Merge branch 'master' of http://10.1.1.202:3030/steve07s/lottery 2 년 전
  maa3520 99ba1f1ff3 新增亂數測試 2 년 전

+ 22 - 2
app/Http/Controllers/DrawController.php

@@ -28,8 +28,7 @@ class DrawController extends Controller
         $prize = Prize::where('id', $request->prize_id)->first();
         if ($prize->count > 0) {
             $activity = Activity::where('id', $request->activity_id)->first();
-            $users = CheckIn::
-            where('activity_id', $request->activity_id)
+            $users = CheckIn::where('activity_id', $request->activity_id)
                 ->where('is_checked_in', 'true')
                 ->where('is_awarded', 'false')
                 ->whereTime('check_ins.updated_at', '<=', $activity->deadline)
@@ -119,4 +118,25 @@ class DrawController extends Controller
             ->where('check_ins.user_id', $request->user_id)
             ->first();
     }
+
+    public function draw_test(Request $request)
+    {
+        
+        $output = [];
+        $draw_count = $request->number;
+        //去掉判斷只保留邏輯
+        for($i = 0; $i < $draw_count ;$i++) {
+            $users = CheckIn::where('activity_id', $request->activity_id)
+                // ->where('is_checked_in', 'true')
+                // ->where('is_awarded', 'false')
+                ->whereIn('region', $request->region)
+                ->join('departments', 'check_ins.department_id', '=', 'departments.department_id')
+                ->inRandomOrder()
+                ->get();
+    
+            $draw_user = $users->random(1);
+            array_push($output,$draw_user[0]->user_id);
+        }
+        return $output;
+    }
 }

+ 22 - 0
resources/js/src/router/config.js

@@ -167,6 +167,28 @@ export const settings = {
                 requiresAuth: true,
             },
         },
+        {
+            path: '/randomTest/:activity_id',
+            name: 'randomTest',
+            component: () => import('@/views/lottery/RandomTest.vue'),
+            meta: {
+                pageTitle: '亂數測試',
+                breadcrumb: [{
+                        text: '活動列表',
+                        to: '/activityList'
+                    },
+                    {
+                        text: '活動功能頁面',
+                        to: '/activityPage'
+                    },
+                    {
+                        text: '亂數測試',
+                        active: true,
+                    },
+                ],
+                requiresAuth: true,
+            },
+        },
         {
             path: '/permission',
             name: 'permission',

+ 24 - 8
resources/js/src/views/lottery/Activities/ActivityPage.vue

@@ -26,14 +26,7 @@
                     </b-card-body>
                 </b-card>
             </b-col>
-            <b-col v-if="canViewVerticalNavMenuLink({route:'slotManager'})" md="6" :lg="lg">
-                <b-card no-body border-variant="info" class="text-center">
-                    <b-card-body>
-                        <b-button variant="success"
-                            :to="{ name: 'slotManager', params: { 'activity_id': this.$route.params.activity_id } }">抽獎管理頁面</b-button>
-                    </b-card-body>
-                </b-card>
-            </b-col>
+
             <b-col v-if="checkinPage.includes(role)" md="6" :lg="lg">
                 <b-card no-body border-variant="info" class="text-center">
                     <b-card-body>
@@ -83,6 +76,29 @@
                     </b-card-body>
                 </b-card>
             </b-col>
+
+        </b-row>
+        <div v-if="canViewVerticalNavMenuLink({ route: 'slotManager' })" class="group-area mt-1">
+            <h3>管理功能</h3>
+            <hr>
+        </div>
+        <b-row class="match-height">
+            <b-col v-if="canViewVerticalNavMenuLink({ route: 'slotManager' })" md="6" :lg="lg">
+                <b-card no-body border-variant="info" class="text-center">
+                    <b-card-body>
+                        <b-button variant="success"
+                            :to="{ name: 'slotManager', params: { 'activity_id': this.$route.params.activity_id } }">抽獎管理頁面</b-button>
+                    </b-card-body>
+                </b-card>
+            </b-col>
+            <b-col v-if="canViewVerticalNavMenuLink({ route: 'slotManager' })" md="6" :lg="lg">
+                <b-card no-body border-variant="info" class="text-center">
+                    <b-card-body>
+                        <b-button variant="success"
+                            :to="{ name: 'randomTest', params: { 'activity_id': this.$route.params.activity_id } }">亂數分布測試</b-button>
+                    </b-card-body>
+                </b-card>
+            </b-col>
         </b-row>
     </div>
 </template>

+ 173 - 0
resources/js/src/views/lottery/RandomTest.vue

@@ -0,0 +1,173 @@
+<template>
+	<div>
+
+		<b-card no-body>
+			<b-card-header>
+				<div>
+					<b-card-title class="mb-1">
+						亂數機率分布
+					</b-card-title>
+				</div>
+				<div class="d-flex align-items-center">
+					<b-button variant="info" @click="draw">隨機抽100次</b-button>
+				</div>
+			</b-card-header>
+
+
+			<!-- chart -->
+			<b-card-body>
+				<chartjs-component-line-chart
+					v-if="loaded"
+					:height="400"
+					:data="randomData"
+					:options="chartjsData.lineChart.options" />
+			</b-card-body>
+		</b-card>
+	</div>
+</template>
+<script>
+import { BRow, BCol, BCard, BCardHeader, BCardBody, BCardTitle, BCardText, BButton, BMedia, BFormInput, BImg, BMediaAside, BMediaBody, BInputGroup, BInputGroupAppend } from 'bootstrap-vue'
+import Ripple from 'vue-ripple-directive'
+import useJwt from '@/auth/jwt/useJwt'
+import ChartjsComponentLineChart from './charts-components/ChartjsComponentLineChart.vue'
+import chartjsData from './charts-components/chartjsData'
+import {
+	$themeColors
+} from '@themeConfig'
+const chartColors = {
+	primaryColorShade: '#836AF9',
+	yellowColor: '#ffe800',
+	successColorShade: '#28dac6',
+	warningColorShade: '#ffe802',
+	warningLightColor: '#FDAC34',
+	infoColorShade: '#299AFF',
+	greyColor: '#4F5D70',
+	blueColor: '#2c9aff',
+	blueLightColor: '#84D0FF',
+	greyLightColor: '#EDF1F4',
+	tooltipShadow: 'rgba(0, 0, 0, 0.25)',
+	lineChartPrimary: '#666ee8',
+	lineChartDanger: '#ff4961',
+	labelColor: '#6e6b7b',
+	grid_line_color: 'rgba(200, 200, 200, 0.2)',
+}
+
+export default {
+	name: "websocket",
+	components: {
+		BRow,
+		BCol,
+		BCard,
+		BCardHeader,
+		BCardBody,
+		BCardTitle,
+		BCardText,
+		BButton,
+		BMedia,
+		BFormInput,
+		BImg,
+		BMediaAside,
+		BMediaBody,
+		BInputGroup,
+		BInputGroupAppend,
+		ChartjsComponentLineChart
+	},
+	directives: {
+		Ripple,
+	},
+	data() {
+		return {
+			loaded: false,
+			activityId: this.$route.params.activity_id,
+			activity: {},
+			userList: [],
+			prizeList: [],
+			chartjsData,
+			rangePicker: ['2019-05-01', '2019-05-10'],
+			randomData: {
+				labels: [],
+				datasets: [
+					{
+						data: [],
+						label: '中獎次數',
+						borderColor: chartColors.lineChartDanger,
+						lineTension: 0.5,
+						pointStyle: 'circle',
+						backgroundColor: chartColors.lineChartDanger,
+						fill: false,
+						pointRadius: 1,
+						pointHoverRadius: 5,
+						pointHoverBorderWidth: 5,
+						pointBorderColor: 'transparent',
+						pointHoverBorderColor: $themeColors.white,
+						pointHoverBackgroundColor: chartColors.lineChartDanger,
+						pointShadowOffsetX: 1,
+						pointShadowOffsetY: 1,
+						pointShadowBlur: 5,
+						pointShadowColor: chartColors.tooltipShadow,
+					}
+				],
+			},
+			data: {},
+		}
+	},
+	created() {
+		this.loaded = false
+		useJwt.postData('/api/check_in/index_by_activity', { activity_id: this.activityId }).then(res => {
+			console.log(res.data)
+
+			this.userList = res.data;
+			let array = Object.keys(res.data);
+			this.randomData.labels = array;
+			this.randomData.datasets[0].data = Array(array.length).fill(0)
+			this.data = array.reduce((acc, curr) => (acc[curr] = 0, acc), {});
+			this.loaded = true
+		});
+
+		useJwt.postData('/api/prize/index_by_activity', { activity_id: this.activityId }).then(res => {
+			console.log(res.data);
+			this.prizeList = res.data;
+		});
+
+	},
+	computed: {
+
+	},
+	methods: {
+		draw() {
+			useJwt.postData('/api/randomTest/draw', {
+				activity_id: this.activityId,
+				prize_id: this.prizeList[2].id,
+				region: ['北區', '中區', '南區', '來賓'],
+				number: 100
+			}).then(res => {
+				this.drawList = res.data;
+				let result = this.countOccurrences(this.data, res.data);
+				this.randomData.datasets[0].data = result;
+				console.log(res.data);
+				console.log(result);
+			});
+		},
+		countOccurrences(obj1, array1) {
+			const obj = obj1;
+			array1.forEach((item) => {
+				if (obj.hasOwnProperty(item)) {
+					obj[item]++;
+				}
+			});
+			this.data = obj;
+			let array2 = Object.values(obj);
+			return array2;
+		}
+	},
+	mounted() {
+
+	},
+	computed: {
+
+	}
+}
+
+</script>
+
+<style></style>

+ 41 - 0
resources/js/src/views/lottery/charts-components/ChartjsComponentLineChart.vue

@@ -0,0 +1,41 @@
+<script>
+import { Line } from 'vue-chartjs'
+
+export default {
+  extends: Line,
+  props: {
+    data: {
+      type: Object,
+      default: null,
+    },
+    options: {
+      type: Object,
+      default: null,
+    },
+    plugins: {
+      type: Array,
+      default: null,
+    },
+    styles: {
+      type: Object,
+      default: null,
+    },
+  },
+  mounted() {
+    this.render();
+  },
+  methods: {
+    render() {
+      this.renderChart(this.data, this.options, this.plugins, this.styles)
+    },
+  },
+  watch: {
+    data: {
+      handler: function (newVal, oldVal) {
+        this.render();
+      },
+      deep: true
+    }
+  },
+}
+</script>

+ 154 - 0
resources/js/src/views/lottery/charts-components/chartjsData.js

@@ -0,0 +1,154 @@
+import {
+    $themeColors
+} from '@themeConfig'
+// colors
+const chartColors = {
+    primaryColorShade: '#836AF9',
+    yellowColor: '#ffe800',
+    successColorShade: '#28dac6',
+    warningColorShade: '#ffe802',
+    warningLightColor: '#FDAC34',
+    infoColorShade: '#299AFF',
+    greyColor: '#4F5D70',
+    blueColor: '#2c9aff',
+    blueLightColor: '#84D0FF',
+    greyLightColor: '#EDF1F4',
+    tooltipShadow: 'rgba(0, 0, 0, 0.25)',
+    lineChartPrimary: '#666ee8',
+    lineChartDanger: '#ff4961',
+    labelColor: '#6e6b7b',
+    grid_line_color: 'rgba(200, 200, 200, 0.2)',
+}
+
+export default {
+    lineChart: {
+        options: {
+            responsive: true,
+            maintainAspectRatio: false,
+            backgroundColor: false,
+            hover: {
+                mode: 'label',
+            },
+            tooltips: {
+                // Updated default tooltip UI
+                shadowOffsetX: 1,
+                shadowOffsetY: 1,
+                shadowBlur: 8,
+                shadowColor: chartColors.tooltipShadow,
+                backgroundColor: $themeColors.white,
+                titleFontColor: $themeColors.black,
+                bodyFontColor: $themeColors.black,
+            },
+            layout: {
+                padding: {
+                    top: -15,
+                    bottom: -25,
+                    left: -15,
+                },
+            },
+            scales: {
+                xAxes: [{
+                    display: true,
+                    scaleLabel: {
+                        display: true,
+                    },
+                    gridLines: {
+                        display: true,
+                        color: chartColors.grid_line_color,
+                        zeroLineColor: chartColors.grid_line_color,
+                    },
+                    ticks: {
+                        fontColor: chartColors.labelColor,
+                    },
+                }, ],
+                yAxes: [{
+                    display: true,
+                    scaleLabel: {
+                        display: true,
+                    },
+                    ticks: {
+                        stepSize: 2,
+                        min: 0,
+                        max: 10,
+                        fontColor: chartColors.labelColor,
+                    },
+                    gridLines: {
+                        display: true,
+                        color: chartColors.grid_line_color,
+                        zeroLineColor: chartColors.grid_line_color,
+                    },
+                }, ],
+            },
+            legend: {
+                position: 'top',
+                align: 'start',
+                labels: {
+                    usePointStyle: true,
+                    padding: 25,
+                    boxWidth: 9,
+                },
+            },
+        },
+        data: {
+            labels: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140],
+            datasets: [{
+                    data: [80, 150, 180, 270, 210, 160, 160, 202, 265, 210, 270, 255, 290, 360, 375],
+                    label: 'Europe',
+                    borderColor: chartColors.lineChartDanger,
+                    lineTension: 0.5,
+                    pointStyle: 'circle',
+                    backgroundColor: chartColors.lineChartDanger,
+                    fill: false,
+                    pointRadius: 1,
+                    pointHoverRadius: 5,
+                    pointHoverBorderWidth: 5,
+                    pointBorderColor: 'transparent',
+                    pointHoverBorderColor: $themeColors.white,
+                    pointHoverBackgroundColor: chartColors.lineChartDanger,
+                    pointShadowOffsetX: 1,
+                    pointShadowOffsetY: 1,
+                    pointShadowBlur: 5,
+                    pointShadowColor: chartColors.tooltipShadow,
+                },
+                {
+                    data: [80, 125, 105, 130, 215, 195, 140, 160, 230, 300, 220, 170, 210, 200, 280],
+                    label: 'Asia',
+                    borderColor: chartColors.lineChartPrimary,
+                    lineTension: 0.5,
+                    pointStyle: 'circle',
+                    backgroundColor: chartColors.lineChartPrimary,
+                    fill: false,
+                    pointRadius: 1,
+                    pointHoverRadius: 5,
+                    pointHoverBorderWidth: 5,
+                    pointBorderColor: 'transparent',
+                    pointHoverBorderColor: $themeColors.white,
+                    pointHoverBackgroundColor: chartColors.lineChartPrimary,
+                    pointShadowOffsetX: 1,
+                    pointShadowOffsetY: 1,
+                    pointShadowBlur: 5,
+                    pointShadowColor: chartColors.tooltipShadow,
+                },
+                {
+                    data: [80, 99, 82, 90, 115, 115, 74, 75, 130, 155, 125, 90, 140, 130, 180],
+                    label: 'Africa',
+                    borderColor: chartColors.warningColorShade,
+                    lineTension: 0.5,
+                    pointStyle: 'circle',
+                    backgroundColor: chartColors.warningColorShade,
+                    fill: false,
+                    pointRadius: 1,
+                    pointHoverRadius: 5,
+                    pointHoverBorderWidth: 5,
+                    pointBorderColor: 'transparent',
+                    pointHoverBorderColor: $themeColors.white,
+                    pointHoverBackgroundColor: chartColors.warningColorShade,
+                    pointShadowOffsetX: 1,
+                    pointShadowOffsetY: 1,
+                    pointShadowBlur: 5,
+                    pointShadowColor: chartColors.tooltipShadow,
+                },
+            ],
+        },
+    },
+}

+ 3 - 0
routes/api.php

@@ -98,6 +98,9 @@ Route::middleware(['auth:sanctum', 'abilities:Admin'])->group(function () {
 
     //DrawManager
     Route::post('/drawManager', [DrawController::class, 'send']);
+
+    //Tester
+    Route::post('/randomTest/draw', [DrawController::class, 'draw_test']);
 });
 
 Route::middleware(['auth:sanctum', 'ability:Draw,Admin'])->group(function () {