index.html 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. {extend name="public/base_el"/}
  2. {block name="css"}
  3. <style>
  4. .box {
  5. width: 800px;
  6. margin: 0 auto;
  7. }
  8. .title {
  9. margin-top: 50px;
  10. text-align: center;
  11. font-size: 24px;
  12. padding-bottom: 50px;
  13. }
  14. .name-list {
  15. display: flex;
  16. align-items: center;
  17. justify-content: space-around;
  18. flex-wrap: wrap;
  19. }
  20. .name-list .name {
  21. width: 266px;
  22. text-align: center;
  23. margin-top: 20px;
  24. font-size: 24px;
  25. }
  26. </style>
  27. {/block}
  28. {block name="body"}
  29. <div class="box">
  30. <div class="input_number" v-show="showBox == 'number'">
  31. <div class="title">请输入人数</div>
  32. <el-row>
  33. <el-col :span="12" :offset="6">
  34. <el-form-item label="抽取人数">
  35. <el-input v-model="number" placeholder="请输入抽取人数"></el-input>
  36. </el-form-item>
  37. </el-col>
  38. </el-row>
  39. <div style="margin-top:50px;text-align: center;">
  40. <el-button type="primary" @click="toSelect">提交</el-button>
  41. <el-button type="primary" @click="onRest">重置</el-button>
  42. </div>
  43. </div>
  44. <div class="select_name" v-show="showBox == 'select'">
  45. <div class="title">抽取中奖人员</div>
  46. <div class="name-list">
  47. <div class="name" v-for="item in list_now">{{item}}</div>
  48. </div>
  49. <div style="margin-top:50px;text-align: center;">
  50. <el-button type="primary" @click="onStart" v-show="status == 'unstart'">开始</el-button>
  51. <el-button type="success" @click="onEnd" v-show="status == 'start'">确定</el-button>
  52. <el-button type="danger" @click="onBack" v-show="status == 'end'">返回</el-button>
  53. </div>
  54. </div>
  55. <div style="margin-top: 10px;">
  56. 已排除人员:
  57. <span v-for="item in ext_list">
  58. <el-tag type="danger" style="margin-left: 10px;margin-top: 5px;">{{item}}</el-tag>
  59. </span>
  60. </div>
  61. </div>
  62. {/block}
  63. {block name="script"}
  64. <script>
  65. function v_setup() {
  66. let base = {};
  67. base.showBox = Vue.ref('number');
  68. base.number = Vue.ref(3);
  69. base.list = Vue.ref({$list});
  70. base.list_now = Vue.ref([]);
  71. base.ext_list = Vue.ref([]);
  72. base.set = null;
  73. base.status = Vue.ref('unstart');
  74. base.toSelect = () => {
  75. base.showBox.value = 'select';
  76. base.status.value = 'unstart';
  77. const { selected, rest } =base.getRandomUniqueItems(base.list.value, base.number.value);
  78. base.list_now.value = selected;
  79. }
  80. base.onRest = () => {
  81. location.reload();
  82. }
  83. base.onStart = () => {
  84. if (base.number.value > base.list.value.length) {
  85. alert('剩余人数不满足需要中奖人数');
  86. return false;
  87. }
  88. base.status.value = 'start';
  89. base.set = setInterval(() => {
  90. const { selected, rest } =base.getRandomUniqueItems(base.list.value, base.number.value);
  91. base.list_now.value = selected;
  92. },100)
  93. }
  94. base.onEnd = () => {
  95. clearInterval(base.set);
  96. const { selected, rest } =base.getRandomUniqueItems(base.list.value, base.number.value);
  97. base.list_now.value = selected;
  98. base.list.value = rest;
  99. base.ext_list.value = [...base.ext_list.value,...selected];
  100. base.status.value = 'end'
  101. }
  102. base.onBack = () => {
  103. base.showBox.value = 'number';
  104. }
  105. base.getRandomUniqueItems = (array, count) => {
  106. const shuffled = [...array];
  107. // 只需打乱前 count 个位置即可(优化版 Fisher-Yates)
  108. for (let i = 0; i < count; i++) {
  109. const j = Math.floor(Math.random() * (array.length - i)) + i;
  110. [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
  111. }
  112. // 前 count 个是随机选出的,后面的是剩余的
  113. const selected = shuffled.slice(0, count);
  114. const rest = shuffled.slice(count);
  115. return {selected, rest};
  116. }
  117. return base;
  118. }
  119. </script>
  120. {/block}