|
|
@@ -0,0 +1,421 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <b-row class="prize-list-wrapper">
|
|
|
+ <b-col md="6">
|
|
|
+ <b-card title="獎項列表" style="height:75vh;">
|
|
|
+ <b-table responsive hover sticky-header=true :items="getPrizeList(prizeList)" bordered :fields="fields"
|
|
|
+ @row-clicked="click" style="max-height: 57vh; overflow: auto;">
|
|
|
+ <template #cell(ICON)="data">
|
|
|
+ <div class="text-center">
|
|
|
+ <feather-icon :icon="data.value" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </b-table>
|
|
|
+ <b-button v-ripple.400="'rgba(255, 255, 255, 0.15)'" class="mt-3" variant="outline-primary" block
|
|
|
+ @click="showAddPrize">
|
|
|
+ 加碼
|
|
|
+ </b-button>
|
|
|
+ </b-card>
|
|
|
+ </b-col>
|
|
|
+
|
|
|
+ <b-modal ref="draw-modal" id="draw-modal" centered title="抽獎" no-stacking hide-footer>
|
|
|
+ <label>獎品:</label>
|
|
|
+ <b-form-input v-model="prize" :disabled=true />
|
|
|
+ <br>
|
|
|
+ <label>地區: </label>
|
|
|
+ <v-select multiple v-model="region" :options="regionOption" />
|
|
|
+ <br>
|
|
|
+ <label>數量: </label>
|
|
|
+ <div class="demo-inline-spacing">
|
|
|
+ <b-form-radio v-model="drawOne" name="some-radios" :value=true>
|
|
|
+ 單抽
|
|
|
+ </b-form-radio>
|
|
|
+ <b-form-radio v-model="drawOne" name="some-radios" :value=false>
|
|
|
+ 全抽
|
|
|
+ </b-form-radio>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <b-button v-ripple.400="'rgba(255, 255, 255, 0.15)'" class="mt-3" variant="outline-secondary" block
|
|
|
+ @click="hideModal">
|
|
|
+ Close
|
|
|
+ </b-button>
|
|
|
+ <b-button v-ripple.400="'rgba(255, 255, 255, 0.15)'" class="mt-2" variant="primary" block @click="draw">
|
|
|
+ Accept
|
|
|
+ </b-button>
|
|
|
+ </b-modal>
|
|
|
+
|
|
|
+ <b-modal ref="draw-error" centered title="抽獎錯誤" no-stacking hide-footer>
|
|
|
+ <b-card-text class="my-1 text-center">
|
|
|
+ 抽獎錯誤
|
|
|
+ </b-card-text>
|
|
|
+ <b-button v-ripple.400="'rgba(255, 255, 255, 0.15)'" class="mt-3" variant="outline-secondary" block
|
|
|
+ @click="hideModal">
|
|
|
+ Close
|
|
|
+ </b-button>
|
|
|
+ </b-modal>
|
|
|
+
|
|
|
+ <b-modal ref="draw-animation" title="得獎者是......" centered no-stacking hide-footer>
|
|
|
+ <br>
|
|
|
+ <div :key="index" v-for="(item, index) in drawList" :class=counterId(index)>
|
|
|
+ <i :datafinal=item.department>部門</i>
|
|
|
+ <div :datafinal=item.userId>
|
|
|
+ <i>0</i>
|
|
|
+ <i>0</i>
|
|
|
+ <i>0</i>
|
|
|
+ <i>0</i>
|
|
|
+ <span :datafinal=item.userName></span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-if="drawOne">
|
|
|
+ <b-button v-ripple.400="'rgba(255, 255, 255, 0.15)'" class="mt-2" variant="outline-primary" block
|
|
|
+ @click="donate">
|
|
|
+ 捐出
|
|
|
+ </b-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <b-button v-ripple.400="'rgba(255, 255, 255, 0.15)'" class="mt-2" variant="primary" block @click="store">
|
|
|
+ Accept
|
|
|
+ </b-button>
|
|
|
+ </b-modal>
|
|
|
+
|
|
|
+ <b-modal ref="add-prize" centered title="加碼" no-stacking hide-footer>
|
|
|
+ <label>獎品:</label>
|
|
|
+ <b-form-input v-model="addPrizeName" />
|
|
|
+ <br>
|
|
|
+ <label>加碼者: </label>
|
|
|
+ <b-form-input v-model="addPrizeUser" />
|
|
|
+ <br>
|
|
|
+ <label>數量: </label>
|
|
|
+ <b-form-spinbutton v-model="addPrizeNumber" min="1" />
|
|
|
+
|
|
|
+ <b-button v-ripple.400="'rgba(255, 255, 255, 0.15)'" class="mt-3" variant="outline-secondary" block
|
|
|
+ @click="hideModal">
|
|
|
+ Close
|
|
|
+ </b-button>
|
|
|
+ <b-button v-ripple.400="'rgba(255, 255, 255, 0.15)'" class="mt-2" variant="primary" block @click="addPrize">
|
|
|
+ Accept
|
|
|
+ </b-button>
|
|
|
+ </b-modal>
|
|
|
+
|
|
|
+ <b-col md="6">
|
|
|
+ <b-card title="抽獎紀錄" style="height:75vh;">
|
|
|
+ <b-table responsive sticky-header=true :items="getRecipientsList(recipientsList)" bordered
|
|
|
+ style="max-height: 65vh; overflow: auto;">
|
|
|
+ <template #cell(ICON)="data">
|
|
|
+ <div class="text-center">
|
|
|
+ <feather-icon :icon="data.value" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </b-table>
|
|
|
+ </b-card>
|
|
|
+ </b-col>
|
|
|
+ </b-row>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { BRow, BCol, BCard, BCardText, BLink, BTable, BModal, BFormInput, BFormSpinbutton, BButton, BFormCheckbox, BFormRadio } from 'bootstrap-vue'
|
|
|
+import useJwt from '@/auth/jwt/useJwt'
|
|
|
+import { VueGoodTable } from 'vue-good-table'
|
|
|
+import vSelect from 'vue-select'
|
|
|
+import Ripple from 'vue-ripple-directive'
|
|
|
+import 'vue-select/dist/vue-select.css';
|
|
|
+
|
|
|
+export default {
|
|
|
+ components: {
|
|
|
+ BRow,
|
|
|
+ BCol,
|
|
|
+ BCard,
|
|
|
+ BCardText,
|
|
|
+ BLink,
|
|
|
+ BTable,
|
|
|
+ BModal,
|
|
|
+ BFormInput,
|
|
|
+ BFormSpinbutton,
|
|
|
+ BButton,
|
|
|
+ BFormCheckbox,
|
|
|
+ BFormRadio,
|
|
|
+ VueGoodTable,
|
|
|
+ vSelect,
|
|
|
+ },
|
|
|
+ directives: {
|
|
|
+ Ripple,
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ activityId: this.$route.params.activity_id,
|
|
|
+ activity: {},
|
|
|
+ userList: [],
|
|
|
+ departmentList: [],
|
|
|
+ prizeList: [],
|
|
|
+ recipientsList: [],
|
|
|
+
|
|
|
+ fields: ['獎項', '數量'],
|
|
|
+ regionOption: ['北區', '中區', '南區', '來賓'],
|
|
|
+ region: ['北區', '中區', '南區', '來賓'],
|
|
|
+ drawMax: 1,
|
|
|
+ drawOne: true,
|
|
|
+
|
|
|
+ prize: '',
|
|
|
+ prizeId: '',
|
|
|
+ drawList: [],
|
|
|
+
|
|
|
+ addPrizeName: '',
|
|
|
+ addPrizeUser: '',
|
|
|
+ addPrizeNumber: 1,
|
|
|
+
|
|
|
+ departments: [
|
|
|
+ "行管部庶務科",
|
|
|
+ "人力資源科",
|
|
|
+ "行管部文書科",
|
|
|
+ "南區辦事處",
|
|
|
+ "中區辦事處",
|
|
|
+ "工程管理一部",
|
|
|
+ "工程管理二部",
|
|
|
+ "發展與企畫部",
|
|
|
+ "工程製圖科",
|
|
|
+ "工務部",
|
|
|
+ "大地工程部",
|
|
|
+ "財務部",
|
|
|
+ "運輸土木部",
|
|
|
+ "城鄉發展部",
|
|
|
+ "軌道工程部",
|
|
|
+ "董事長室",
|
|
|
+ "總經理室",
|
|
|
+ "企業發展中心",
|
|
|
+ "成本中心",
|
|
|
+ "資訊中心",
|
|
|
+ "環境水務部",
|
|
|
+ "環境永續部",
|
|
|
+ "機電工程部",
|
|
|
+ "結構工程部",
|
|
|
+ "工程設計群",
|
|
|
+ "工程監理群",
|
|
|
+ "總管理處",
|
|
|
+ "建築及設施群",
|
|
|
+ "數位發展部",
|
|
|
+ "淡海輕軌專案",
|
|
|
+ "安坑輕軌專案",
|
|
|
+ "先進技術中心",
|
|
|
+ "塭仔圳專案",
|
|
|
+ "萬大市場專案",
|
|
|
+ "來賓"
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+
|
|
|
+
|
|
|
+ useJwt.postData('/api/activity/show', { activity_id: this.activityId }).then(res => {
|
|
|
+ this.activity = res.data;
|
|
|
+ });
|
|
|
+
|
|
|
+ useJwt.postData('/api/check_in/index_by_activity', { activity_id: this.activityId }).then(res => {
|
|
|
+ this.userList = res.data;
|
|
|
+ });
|
|
|
+
|
|
|
+ useJwt.postData('/api/prize/index_by_activity', { activity_id: this.activityId }).then(res => {
|
|
|
+ this.prizeList = res.data;
|
|
|
+ });
|
|
|
+
|
|
|
+ useJwt.postData('/api/recipients/index_by_activity', { activity_id: this.activityId }).then(res => {
|
|
|
+ this.recipientsList = res.data;
|
|
|
+ });
|
|
|
+
|
|
|
+ useJwt.postData('/api/department/index').then(res => {
|
|
|
+ this.departmentList = res.data;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ dateFormat(date) {
|
|
|
+ var d = new Date(date);
|
|
|
+ return d.getFullYear()
|
|
|
+ + '/' + (d.getMonth() + 1).toString().padStart(2, '0')
|
|
|
+ + '/' + d.getDay().toString().padStart(2, '0')
|
|
|
+ + '/' + d.getHours().toString().padStart(2, '0')
|
|
|
+ + ':' + d.getMinutes().toString().padStart(2, '0')
|
|
|
+ + ':' + d.getSeconds().toString().padStart(2, '0');
|
|
|
+ },
|
|
|
+ getPrizeList(prizeList) {
|
|
|
+ var output = [];
|
|
|
+ prizeList.forEach(element => {
|
|
|
+ output.push({ id: element.id, '獎項': element.name, '數量': element.count });
|
|
|
+ });
|
|
|
+ return output;
|
|
|
+ },
|
|
|
+ getPrizeName(prizeId) {
|
|
|
+ var output = '';
|
|
|
+ this.prizeList.forEach(element => {
|
|
|
+ if (prizeId == element.id) {
|
|
|
+ output = element.name;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return output;
|
|
|
+ },
|
|
|
+ getRecipientsList(recipientsList) {
|
|
|
+ var output = [];
|
|
|
+ recipientsList.forEach(element => {
|
|
|
+ output.push({ '獎項': this.getPrizeName(element.prize_id), '獲獎人': this.userList[element.user_id], '時間': this.dateFormat(element.created_at) });
|
|
|
+ });
|
|
|
+ return output;
|
|
|
+ },
|
|
|
+ counterId(id) {
|
|
|
+ return "counter_" + id;
|
|
|
+ },
|
|
|
+ drawNumber() {
|
|
|
+ if (this.drawOne) {
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ return this.drawMax;
|
|
|
+ },
|
|
|
+ showDraw() {
|
|
|
+ this.$refs['draw-modal'].show();
|
|
|
+ },
|
|
|
+ showDrawAnimation() {
|
|
|
+ this.$refs['draw-animation'].show();
|
|
|
+ },
|
|
|
+ showAddPrize() {
|
|
|
+ this.$refs['add-prize'].show();
|
|
|
+ },
|
|
|
+ showDrawError() {
|
|
|
+ this.$refs['draw-error'].show();
|
|
|
+ },
|
|
|
+ hideModal() {
|
|
|
+ this.$refs['draw-modal'].hide();
|
|
|
+ this.$refs['draw-error'].hide();
|
|
|
+ this.$refs['draw-animation'].hide();
|
|
|
+ this.$refs['add-prize'].hide();
|
|
|
+ this.updateDataset();
|
|
|
+ },
|
|
|
+ updateDataset() {
|
|
|
+ useJwt.postData('/api/prize/index_by_activity', { activity_id: this.activityId }).then(res => {
|
|
|
+ this.prizeList = res.data;
|
|
|
+ });
|
|
|
+ useJwt.postData('/api/recipients/index_by_activity', { activity_id: this.activityId }).then(res => {
|
|
|
+ this.recipientsList = res.data;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ click(params) {
|
|
|
+ this.prize = this.getPrizeName(params.id);
|
|
|
+ this.prizeId = params.id;
|
|
|
+ this.drawOne = true;
|
|
|
+ this.drawMax = params["數量"];
|
|
|
+ this.drawList = [];
|
|
|
+ if (this.drawMax == 0) {
|
|
|
+ this.showDrawError();
|
|
|
+ } else {
|
|
|
+ this.showDraw();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ draw() {
|
|
|
+ useJwt.postData('/api/draw/draw', {
|
|
|
+ activity_id: this.activityId,
|
|
|
+ prize_id: this.prizeId,
|
|
|
+ region: this.region,
|
|
|
+ number: this.drawNumber()
|
|
|
+ }).then(res => {
|
|
|
+ if (res.data) {
|
|
|
+ this.drawList = res.data;
|
|
|
+ setTimeout(() => {
|
|
|
+ this.count();
|
|
|
+ }, 500);
|
|
|
+ this.showDrawAnimation();
|
|
|
+ } else {
|
|
|
+ this.showDrawError();
|
|
|
+ console.log("draw error");
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ store() {
|
|
|
+ var idList = [];
|
|
|
+ this.drawList.forEach(element => {
|
|
|
+ idList.push(element.user_id);
|
|
|
+ });
|
|
|
+ useJwt.postData('/api/draw/store', {
|
|
|
+ users: idList,
|
|
|
+ prize_id: String(this.prizeId),
|
|
|
+ number: this.drawNumber()
|
|
|
+ }).then(res => {
|
|
|
+ if (res.data) {
|
|
|
+ console.log("store success");
|
|
|
+ } else {
|
|
|
+ console.log("store error");
|
|
|
+ }
|
|
|
+ this.hideModal();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ donate() {
|
|
|
+ var idList = [];
|
|
|
+ this.drawList.forEach(element => {
|
|
|
+ idList.push(element.user_id);
|
|
|
+ });
|
|
|
+ useJwt.postData('/api/draw/donate', { users: idList }).then(res => {
|
|
|
+ if (res.data) {
|
|
|
+ console.log("donate success");
|
|
|
+ } else {
|
|
|
+ console.log("donate error");
|
|
|
+ }
|
|
|
+ this.hideModal();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ addPrize() {
|
|
|
+ useJwt.postData('/api/prize/store', {
|
|
|
+ activity_id: this.activityId,
|
|
|
+ name: this.addPrizeName,
|
|
|
+ provider: this.addPrizeUser,
|
|
|
+ count: this.addPrizeNumber
|
|
|
+ }).then(res => {
|
|
|
+ if (res.data) {
|
|
|
+ console.log("add prize success");
|
|
|
+ } else {
|
|
|
+ console.log("add prize error");
|
|
|
+ }
|
|
|
+ this.hideModal();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ count() {
|
|
|
+ var departments = this.departments;
|
|
|
+ var numbers = "0123456789"
|
|
|
+ var string = numbers;
|
|
|
+
|
|
|
+ this.drawList.forEach((element, index) => {
|
|
|
+ var departmentName = this.departmentList[element.department_id];
|
|
|
+ var deps = document.querySelectorAll(".counter_" + index + " > i");
|
|
|
+ var allCounters = document.querySelectorAll(".counter_" + index + " > div > i");
|
|
|
+
|
|
|
+ deps.forEach(function (el) {
|
|
|
+ var duration = 1000;
|
|
|
+ var interval = setInterval(function () {
|
|
|
+ el.innerText = departments[Math.floor(Math.random() * departments.length)];
|
|
|
+ duration = duration - 50;
|
|
|
+ if (duration <= 0) {
|
|
|
+ clearInterval(interval);
|
|
|
+ el.innerText = departmentName;
|
|
|
+ }
|
|
|
+ }, 50);
|
|
|
+ });
|
|
|
+ allCounters.forEach((el, i) => {
|
|
|
+ var duration = 500 + i * 1000;
|
|
|
+ var interval = setInterval(e => {
|
|
|
+ el.innerText = string.charAt(Math.random() * string.length);
|
|
|
+ duration = duration - 50;
|
|
|
+ if (duration <= 0) {
|
|
|
+ clearInterval(interval);
|
|
|
+ el.innerText = element.user_id[i];
|
|
|
+ if (i == 3) {
|
|
|
+ document.querySelectorAll(".counter_" + index + " > div > span")[0].innerText = element.user_name;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, 50);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ },
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+@import '~@resources/scss/vue/libs/vue-select.scss';
|
|
|
+</style>
|
|
|
+
|