Browse Source

Merge branch 'lihuilin/feature-20250718094329-25周年庆后台' of http://39.101.133.168:8807/lihuilin/AnniversaryBackstage into lihuilin/feature-20250718094329-25周年庆后台

lihuilin/feature-20250718094329-25周年庆后台
lhl 4 weeks ago
parent
commit
1c5704dcc2
  1. 12
      activitylink/.env.development
  2. 15
      activitylink/.env.production
  3. 24
      activitylink/.gitignore
  4. 3
      activitylink/.vscode/extensions.json
  5. 10
      activitylink/README.md
  6. 13
      activitylink/index.html
  7. 1459
      activitylink/package-lock.json
  8. 21
      activitylink/package.json
  9. 1
      activitylink/public/vite.svg
  10. 9
      activitylink/src/App.vue
  11. 4
      activitylink/src/api/API.js
  12. 40
      activitylink/src/api/manage/activity.js
  13. 101
      activitylink/src/api/manage/gift.js
  14. 60
      activitylink/src/api/manage/level.js
  15. 15
      activitylink/src/api/manage/login.js
  16. 9
      activitylink/src/api/manage/win.js
  17. 1
      activitylink/src/assets/vue.svg
  18. 0
      activitylink/src/global.d.ts
  19. BIN
      activitylink/src/img/1.jpg
  20. BIN
      activitylink/src/img/image.png
  21. 20
      activitylink/src/main.js
  22. 74
      activitylink/src/router/index.js
  23. 21
      activitylink/src/stone/activityStone.js
  24. 21
      activitylink/src/stone/counter.js
  25. 21
      activitylink/src/stone/giftFixedListStone.js
  26. 79
      activitylink/src/style.css
  27. 30
      activitylink/src/utils/request.js
  28. 116
      activitylink/src/views/homePage.vue
  29. 287
      activitylink/src/views/zhongchou/activity/detail/index.vue
  30. 322
      activitylink/src/views/zhongchou/activity/index.vue
  31. 179
      activitylink/src/views/zhongchou/activity/set/index.vue
  32. 146
      activitylink/src/views/zhongchou/gift/importFixedList/index.vue
  33. 233
      activitylink/src/views/zhongchou/gift/importuser/index.vue
  34. 416
      activitylink/src/views/zhongchou/gift/index.vue
  35. 101
      activitylink/src/views/zhongchou/index.vue
  36. 279
      activitylink/src/views/zhongchou/level/index.vue
  37. 35
      activitylink/src/views/zhongchou/mainImg/DefaultImage.vue
  38. 255
      activitylink/src/views/zhongchou/winning/index.vue
  39. 24
      activitylink/vite.config.js

12
activitylink/.env.development

@ -0,0 +1,12 @@
# must start with VITE_
VITE_ENV = 'development'
VITE_OUTPUT_DIR = 'dev'
# public path
VITE_PUBLIC_PATH = /
#新数据接口
# VITE_APP_BASE_API = 'http://47.92.148.30:3003/mock/3267'
# VITE_APP_BASE_API = '/api'
# Whether to open mock
VITE_USE_MOCK = true

15
activitylink/.env.production

@ -0,0 +1,15 @@
# must start with VITE_
VITE_ENV = 'production'
VITE_OUTPUT_DIR = 'dist'
# public path
VITE_PUBLIC_PATH = /aixiaocaishen
# VITE_PUBLIC_PATH = /
# Whether to open mock
VITE_USE_MOCK = true
#新数据接口
# VITE_APP_API_BASE_URL = https://api.homilychart.com/link
VITE_BUILD_COMPRESS = 'none'
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false

24
activitylink/.gitignore

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

3
activitylink/.vscode/extensions.json

@ -0,0 +1,3 @@
{
"recommendations": ["Vue.volar"]
}

10
activitylink/README.md

@ -0,0 +1,10 @@
# Vue 3 + Vite
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
Learn more about IDE Support for Vue in the [Vue Docs Scaling up Guide](https://vuejs.org/guide/scaling-up/tooling.html#ide-support).
npm install
npm install vue-router
npm install axios
npm install element-plus --save

13
activitylink/index.html

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>周年庆后台 V1.0</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

1459
activitylink/package-lock.json
File diff suppressed because it is too large
View File

21
activitylink/package.json

@ -0,0 +1,21 @@
{
"name": "activitylink",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite --host",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@vitejs/plugin-vue": "^4.6.2",
"axios": "^1.10.0",
"element-plus": "^2.10.4",
"file-saver": "^2.0.5",
"pinia": "^3.0.3",
"vite": "^4.5.3",
"vue": "^3.5.17",
"vue-router": "^4.5.1"
}
}

1
activitylink/public/vite.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

9
activitylink/src/App.vue

@ -0,0 +1,9 @@
<script setup>
</script>
<template>
<router-view></router-view>
</template>
<style scoped>
</style>

4
activitylink/src/api/API.js

@ -0,0 +1,4 @@
import request from "../utils/request";
const APIurl = import.meta.env.VITE_APP_API_BASE_URL;

40
activitylink/src/api/manage/activity.js

@ -0,0 +1,40 @@
import request from '@/utils/request'
export function getActivityList() {
return request({
url: '/admin/funding/getActivity',
method: 'get',
})
}
export function changeStatusbyId(id,status) {
return request({
url: '/admin/funding/updateActivityStatus',
method: 'post',
params: { id,status }
})
}
/**
* 添加活动
* @param {Object} data 活动数据对象
* @returns Promise
*/
export function addActivityandtime(data) {
return request({
url: '/admin/funding/addActivity',
method: 'post',
data // 使用 data 字段发送请求体(JSON 格式)
})
}
export function getDetailList() {
return request({
url: '/admin/funding/getActivityDetail',
method: 'post',
})
}

101
activitylink/src/api/manage/gift.js

@ -0,0 +1,101 @@
import request from '@/utils/request'
//奖品新增
export function addPrize(data) {
return request({
url: '/admin/prize/add',
method: 'post',
data: data,
headers: {
'Content-Type': 'application/json'
}
})
}
// 奖品删除
export function deletePrize(id) {
return request({
url: '/admin/prize/delete',
method: 'post',
params: { id }
})
}
//奖品分页查询
export function getPrizeList(params) {
return request({
url: '/admin/prize/list',
method: 'post',
params: params
})
}
// 根据id查询奖品
export function getprizebyid(params) {
return request({
url: '/admin/prize/detail',
method: 'post',
params: params
})
}
// 修改奖品
export function updatePrize(data) {
return request({
url: '/admin/prize/update',
method: 'post',
data: data,
headers: {
'Content-Type': 'application/json'
}
})
}
// 查询普通用户
export function getUserList(data) {
return request({
url: '/admin/user/list',
method: 'post',
data: data,
headers: {
'Content-Type': 'application/json'
}
})
}
// 普通用户新增
export function addUser(data) {
return request({
url: '/admin/user/add',
method: 'post',
data: data,
headers: {
'Content-Type': 'application/json'
}
})
}
// 普通用户删除
export function deleteUser(id) {
return request({
url: '/admin/user/delete',
method: 'post',
params: { id },
headers: {
'Content-Type': 'application/json'
}
})
}
// 普通用户批量删除
export function deleteUsers(ids) {
return request({
url: '/admin/user/delete/batch',
method: 'post',
params: { ids }
})
}
// 内定用户查全部
export function getFixUserList(data) {
return request({
url: '/admin/user/list/fix',
method: 'get',
data: data,
headers: {
'Content-Type': 'application/json'
}
})
}

60
activitylink/src/api/manage/level.js

@ -0,0 +1,60 @@
import request from '@/utils/request'
// 等级查询
export function getLevelList(params) {
return request({
url: '/admin/grade/list',
method: 'post',
params: params
})
}
// 等级新增
export function addLevel(data) {
return request({
url: '/admin/grade/add',
method: 'post',
data,
headers: {
'Content-Type': 'application/json'
}
})
}
// 删除等级
export function deleteGrade(id) {
return request({
url: '/admin/grade/delete',
method: 'post',
params: { id }
})
}
// 根据id查询等级
// export function getgradedetails(params) {
// return request({
// url: '/admin/grade/details',
// method: 'post',
// params: params
// })
// }
// 修改等级
export function updateGrade(data) {
return request({
url: '/admin/grade/update',
method: 'post',
data,
headers: {
'Content-Type': 'application/json'
}
})
}
// 等级名下拉框,礼品新增那边
export function getGradeNameList() {
return request({
url: '/admin/grade/allGradeName',
method: 'post',
headers: {
'Content-Type': 'application/json'
}
})
}

15
activitylink/src/api/manage/login.js

@ -0,0 +1,15 @@
// src/api/user.js
import request from '@/utils/request'
/**
* 用户登录
* @param {Object} data 包含 username password
* @returns Promise
*/
export function adminlogin(data) {
return request({
url: '/admin/user/login', // 替换为你的实际接口地址
method: 'post',
data
})
}

9
activitylink/src/api/manage/win.js

@ -0,0 +1,9 @@
import request from '@/utils/request'
export function deleteUser(id) {
return request({
url: '/admin/user/delete',
method: 'post',
params: { id }
})
}

1
activitylink/src/assets/vue.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

0
activitylink/src/global.d.ts

BIN
activitylink/src/img/1.jpg

After

Width: 5244  |  Height: 2950  |  Size: 2.1 MiB

BIN
activitylink/src/img/image.png

After

Width: 71  |  Height: 70  |  Size: 7.6 KiB

20
activitylink/src/main.js

@ -0,0 +1,20 @@
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import './style.css'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import axios from 'axios'
// createApp(App).use(router).mount('#app')
const app = createApp(App)
const pinia = createPinia()
window.axios = axios
// axios.defaults.baseURL = 'http://47.92.148.30:3003/mock/3267'
app.use(router)
app.use(pinia)
app.use(ElementPlus, {
locale: zhCn,
})
app.mount('#app')

74
activitylink/src/router/index.js

@ -0,0 +1,74 @@
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{
path: '/',
redirect: 'homePage'
},
{
path: '/homePage',
name: 'homePage',
component: () => import('../views/homePage.vue'),
// children: [
// {name: 'AiEmotion', path: '/AiEmotion', component: () => import('@/views/AiEmotion.vue')}
// ]
},
{
path: '/zhongchou',
name: 'zhongchou',
component: () => import('../views/zhongchou/index.vue'),
children: [
{
path: 'levelManagement', // 注意这里不要加斜杠,表示相对路径
name: 'zhongchoulevel',
component: () => import('../views/zhongchou/level/index.vue'),
},
{
path: 'giftManagement', // 注意这里不要加斜杠,表示相对路径
name: 'zhongchougift',
component: () => import('../views/zhongchou/gift/index.vue'),
},
{
path: 'giftManagement/importUsers', // 注意这里不要加斜杠,表示相对路径
name: 'importUsers',
component: () => import('../views/zhongchou/gift/importuser/index.vue'),
},
{
path: 'giftManagement/importFixedList', // 注意这里不要加斜杠,表示相对路径
name: 'importFixedList',
component: () => import('../views/zhongchou/gift/importFixedList/index.vue'),
},
{
path: 'winningManagement', // 注意这里不要加斜杠,表示相对路径
name: 'zhongchouwinning',
component: () => import('../views/zhongchou/winning/index.vue'),
},
{
path: 'activityManagement', // 注意这里不要加斜杠,表示相对路径
name: 'zhongchouactivity',
component: () => import('../views/zhongchou/activity/index.vue'),
},
{
path: 'activityManagement/detail', // 注意这里不要加斜杠,表示相对路径
name: 'activityDetail',
component: () => import('../views/zhongchou/activity/detail/index.vue'),
},
{
path: 'activityManagement/set', // 注意这里不要加斜杠,表示相对路径
name: 'activitySet',
component: () => import('../views/zhongchou/activity/set/index.vue'),
},
{
path: 'mainimg', // 注意这里不要加斜杠,表示相对路径
name: 'mainImg',
component: () => import('../views/zhongchou/mainImg/DefaultImage.vue'),
}
]
}
]
// 创建路由实例
const router = createRouter({
history: createWebHistory(import.meta.env.VITE_PUBLIC_PATH),
routes
})
// 导出
export default router

21
activitylink/src/stone/activityStone.js

@ -0,0 +1,21 @@
// src/stone/giftFixedListStone.js
import { defineStore } from "pinia";
import { ref } from 'vue';
export const useactivitytone = defineStore('activityStone', () => {
// 响应式属性
const selectactivityId = ref(0);
// 方法
const setselectedactivityId = (name) => {
selectactivityId.value = name;
};
// 暴露出去
return {
selectactivityId,
setselectedactivityId,
};
});

21
activitylink/src/stone/counter.js

@ -0,0 +1,21 @@
import {computed, ref} from 'vue'
import { defineStore } from 'pinia'
export const UseCounterStore = defineStore('counter',()=>{
const count = ref(0)
const add = () =>{
count.value++
}
const sub = () =>{
count.value--
}
const double = computed(()=>{return count.value*2})
const msg=ref('hello')
return {count,add,sub,double,msg}
},{
persist:true
})

21
activitylink/src/stone/giftFixedListStone.js

@ -0,0 +1,21 @@
// src/stone/giftFixedListStone.js
import { defineStore } from "pinia";
import { ref } from 'vue';
export const usegiftFixedListStone = defineStore('giftFixedListStone', () => {
// 响应式属性
const fixedGiftName = ref('666666');
// 方法
const setFixedGiftName = (name) => {
fixedGiftName.value = name;
};
// 暴露出去
return {
fixedGiftName,
setFixedGiftName,
};
});

79
activitylink/src/style.css

@ -0,0 +1,79 @@
:root {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
/* place-items: center; */
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
.card {
padding: 2em;
}
#app {
/* max-width: 1280px; */
/* margin: 0 auto; */
/* padding: 2rem; */
/* text-align: center; */
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}

30
activitylink/src/utils/request.js

@ -0,0 +1,30 @@
import axios from 'axios'
import { ElMessage } from 'element-plus'
// 创建基础实例
const service = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_API,
timeout: 10000
})
// 请求拦截器(简化版)
service.interceptors.request.use(config => {
// 添加token逻辑(如果存在)
const token = localStorage.getItem('token')
if (token) {
config.headers['Authorization'] = 'Bearer ' + token
}
return config
})
// 响应拦截器(简化版)
service.interceptors.response.use(
response => response.data,
error => {
ElMessage.error(error.message || '请求错误')
return Promise.reject(error)
}
)
export default service

116
activitylink/src/views/homePage.vue

@ -0,0 +1,116 @@
<template>
<div class="login-container">
<div class="login-box">
<h2>登录</h2>
<form @submit.prevent="login">
<div class="input-group">
<label for="username">用户名</label>
<input type="text" id="username" v-model="username" required>
</div>
<div class="input-group">
<label for="password">密码</label>
<input type="password" id="password" v-model="password" required>
</div>
<button type="submit" @click="loginHandler">登录</button>
</form>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { useRouter } from "vue-router";
import { ElMessage } from 'element-plus'
import { adminlogin } from '@/api/manage/login'
const router = useRouter();
const username = ref("");
const password = ref("");
// username.value=='90038794' && password.value=='697522'
const loginHandler = async () => {
// try {
// const response = await adminlogin({
// username: username.value,
// password: password.value
// })
router.push('/zhongchou/mainimg')
// code == 200
// if (response.code ) {
// const token = response.code
// // token localStorage
// localStorage.setItem('token', token)
// ElMessage.success('使')
// router.push('/zhongchou/mainimg')
// } else {
// ElMessage.error(response.message || '')
// }
// } catch (error) {
// ElMessage.error('')
// console.error(':', error)
// }
}
</script>
<style scoped>
.login-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url('@/img/1.jpg') no-repeat center center fixed;
background-size: cover;
background-position: center;
z-index: 0;
/* 使用 Flexbox 布局 */
display: flex;
justify-content: center;
align-items: center;
}
.login-box {
background-color: rgba(255, 255, 255, 0.9);
padding: 2rem;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 400px;
z-index: 1; /* 提高 z-index 确保覆盖背景 */
}
h2 {
text-align: center;
margin-bottom: 1.5rem;
}
.input-group {
margin-bottom: 1rem;
}
.input-group label {
display: block;
margin-bottom: 0.5rem;
}
.input-group input {
width: 100%;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
width: 100%;
padding: 0.75rem;
border: none;
border-radius: 4px;
background-color: #42b983;
color: white;
font-size: 1rem;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #369d6e;
}
</style>

287
activitylink/src/views/zhongchou/activity/detail/index.vue

@ -0,0 +1,287 @@
<!-- 美股是0 港股是1 精网号现在用的是字符串类型-->
<template>
<el-card style="margin-top:50px ; min-height: 90vh; max-height: 90vh;">
<div class="gray-container">
<el-button type="primary" @click="goBack">
<i class="el-icon-back"></i> 返回
</el-button>
<!-- 顶部信息栏 -->
<div class="info-bar">
当前总参与人数{{ totalParticipants }} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
参与美股总人数{{ usParticipants }} &nbsp;&nbsp;&nbsp;&nbsp; 美股助力总次数{{ usAssists }} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
参与港股总人数{{ hkParticipants }} &nbsp;&nbsp;&nbsp;&nbsp; 港股助力总次数{{ hkAssists }} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</div>
<!-- 搜索栏 -->
<el-form :inline="true" class="search-bar">
<el-form-item label="姓名">
<el-input v-model="searchdata.name" placeholder="请输入姓名"></el-input>
</el-form-item>
<el-form-item label="精网号">
<el-input v-model="searchdata.jingwangId" placeholder="请输入精网号" @input="handleJingwangIdInput"></el-input>
</el-form-item>
<el-form-item label="市场" class="market-item">
<el-select v-model="searchdata.market" placeholder="请选择" class="market-select">
<el-option label="全部" value="0"></el-option>
<el-option label="美股" value="1"></el-option>
<el-option label="港股" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSearch">搜索</el-button>
</el-form-item>
<el-form-item>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleExport">导出数据</el-button>
</el-form-item>
</el-form>
<!-- 表格 -->
<div class="table-container">
<el-table :data="currentPageData" style="width: 100%" :row-style="{ height: '55px' }">
<el-table-column prop="id" label="ID" width="100" align="center"></el-table-column>
<el-table-column prop="name" label="姓名" width="300" align="center"></el-table-column>
<el-table-column prop="jingwangId" label="精网号" width="300" align="center"></el-table-column>
<el-table-column prop="market" label="参与市场" width="300" align="center">
<template #default="scope">
<span v-if="scope.row.market == '0' ">美股</span>
<span v-if="scope.row.market == '1' ">港股</span>
</template>
</el-table-column>
<el-table-column prop="participationTime" label="参与时间" align="center"></el-table-column>
</el-table>
</div>
</div>
<!-- 返回按钮 -->
<!-- 分页 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="tableData.length"
>
</el-pagination>
</el-card>
</template>
<script setup>
import { ref, computed } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
//
const totalParticipants = ref(156)
const usParticipants = ref(78)
const usAssists = ref(345)
const hkParticipants = ref(78)
const hkAssists = ref(234)
const searchdata = ref({
name: '',
jingwangId: '',
market: ''
})
const tableData = ref([
{
id: 1,
name: '张家伟',
jingwangId: '90047666',
market: '0',
participationTime: '2025年7月11日 09:46'
},
{
id: 2,
name: '张三',
jingwangId: '90047666',
market: '1',
participationTime: '2025年7月11日 09:46'
},
{
id: 2,
name: '张三',
jingwangId: '90047666',
market: '1',
participationTime: '2025年7月11日 09:46'
},
{
id: 2,
name: '张三',
jingwangId: '90047666',
market: '1',
participationTime: '2025年7月11日 09:46'
},
{
id: 2,
name: '张三',
jingwangId: '90047666',
market: '1',
participationTime: '2025年7月11日 09:46'
},
{
id: 2,
name: '张三',
jingwangId: '90047666',
market: '1',
participationTime: '2025年7月11日 09:46'
},
{
id: 2,
name: '张三',
jingwangId: '90047666',
market: '1',
participationTime: '2025年7月11日 09:46'
},
{
id: 2,
name: '张三',
jingwangId: '90047666',
market: '1',
participationTime: '2025年7月11日 09:46'
},
{
id: 2,
name: '张三',
jingwangId: '90047666',
market: '1',
participationTime: '2025年7月11日 09:46'
},
{
id: 2,
name: '张三',
jingwangId: '90047666',
market: '1',
participationTime: '2025年7月11日 09:46'
},
{
id: 2,
name: '张三',
jingwangId: '90047666',
market: '1',
participationTime: '2025年7月11日 09:46'
},
{
id: 2,
name: '张三',
jingwangId: '90047666',
market: '1',
participationTime: '2025年7月11日 09:46'
},
{
id: 2,
name: '张三',
jingwangId: '90047666',
market: '1',
participationTime: '2025年7月11日 09:46'
},
{
id: 2,
name: '张三',
jingwangId: '90047666',
market: '1',
participationTime: '2025年7月11日 09:46'
},
{
id: 2,
name: '张三',
jingwangId: '90047666',
market: '1',
participationTime: '2025年7月11日 09:46'
}
])
const currentPage = ref(1)
const pageSize = ref(10)
//
const currentPageData = computed(() => {
const start = (currentPage.value - 1) * pageSize.value
const end = start + pageSize.value
return tableData.value.slice(start, end)
})
//
const goBack = () => {
router.back()
}
//
const handleSearch = () => {
console.log('Search:', searchdata.value)
}
//
const handleReset = () => {
searchdata.value = {
name: '',
jingwangId: '',
market: ''
}
}
//
const handleExport = () => {
console.log('Export Data')
}
// size
const handleSizeChange = (val) => {
pageSize.value = val
currentPage.value = 1
}
//
const handleCurrentChange = (val) => {
currentPage.value = val
}
//
const handleJingwangIdInput = (value) => {
searchdata.value.jingwangId = value.replace(/\D/g, '')
}
</script>
<style scoped>
.info-bar {
margin: 10px 0;
font-size: 16px;
}
.gray-container {
width: 100%; /* 宽度自适应 */
background-color: #ffffff; /* 浅灰色背景 */
padding: 20px; /* 内边距 */
box-sizing: border-box; /* 包含内边距在总宽度内 */
min-height: 80vh; /* 设置最小高度 */
overflow-x: hidden;
}
.search-bar {
margin-bottom: 20px;
}
.market-item {
width: 200px; /* 根据需要调整宽度 */
}
.market-select {
width: 100%; /* 确保 select 宽度与 form-item 一致 */
}
.table-container {
height: 600px; /* 根据需要调整高度 */
overflow-y: auto; /* 启用垂直滚动条 */
}
</style>

322
activitylink/src/views/zhongchou/activity/index.vue

@ -0,0 +1,322 @@
<template>
<!-- 1代表活动进行中 0代表活动已结束 -->
<el-card style="margin-top:50px; ; min-height: 90vh; max-height: 90vh; ">
<!-- <div style="width: 100%;"> -->
<!-- 活动管理 -->
<!-- 这里可以添加等级管理的具体内容 -->
<div class="gray-container">
<div class="activity-header">
<div class="header-text">活动设置</div>
<el-button type="primary" @click="addActivityShow">添加活动</el-button>
</div>
<!-- 其他内容区域 -->
<div class="content-area">
<el-table :data="currentPageData" style="width: auto" :row-style="{ height: '60px' }">
<el-table-column prop="activityName" label="活动名称"></el-table-column>
<el-table-column prop="marketOne" label="股票一"></el-table-column>
<el-table-column prop="marketTwo" label="股票二"></el-table-column>
<!-- 新增两列 -->
<el-table-column prop="startTime" label="开始时间"></el-table-column>
<el-table-column prop="endTime" label="结束时间"></el-table-column>
<el-table-column label="数据统计">
<template #default="scope">
<a href="#" style="color: red;" @click.prevent="goToDetail(scope.row)">查看详情</a>
</template>
</el-table-column>
<el-table-column label="设置数据">
<template #default="{ $index }">
<a href="#" style="color: red;" @click.prevent="goToSet">设置</a>
</template>
</el-table-column>
<el-table-column label="状态">
<template #default="{ row }">
<el-switch
v-model="row.status"
:active-value="1"
:inactive-value="0"
active-color="#13ce66"
inactive-color="#ff4949"
@change="() => updateStatus(row)"
/>
</template>
</el-table-column>
</el-table>
<el-dialog
v-model="centerDialogVisible"
title="添加活动"
width="500"
align-center
@closed="cancel"
>
<el-form ref="addForm" :model="activity" label-width="80px">
<el-form-item label="活动名称" prop="activityName">
<el-input v-model="activity.activityName" placeholder="请输入活动名称" />
</el-form-item>
<el-form-item label="股票一" prop="marketOne">
<el-input v-model="activity.marketOne" placeholder="请输入股票一" />
</el-form-item>
<el-form-item label="股票二" prop="marketTwo">
<el-input v-model="activity.marketTwo" placeholder="请输入股票二" />
</el-form-item>
<el-form-item label="活动状态" prop="status">
<el-select v-model="activity.status" placeholder="请选择活动状态">
<el-option label="启用" value="1" />
<el-option label="禁用" value="0" />
</el-select>
</el-form-item>
<!-- 新增开始时间 -->
<el-form-item label="开始时间" prop="startTime">
<el-date-picker
v-model="activity.startTime"
type="datetime"
placeholder="请选择开始时间"
value-format="YYYY-MM-DD"
format="YYYY-MM-DD"
style="width: 100%"
/>
</el-form-item>
<!-- 新增结束时间 -->
<el-form-item label="结束时间" prop="endTime">
<el-date-picker
v-model="activity.endTime"
type="datetime"
placeholder="请选择结束时间"
value-format="YYYY-MM-DD"
format="YYYY-MM-DD"
style="width: 100%"
/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="addActivity">
提交
</el-button>
</div>
</template>
</el-dialog>
</div>
</div>
<!-- 分页控件移动到这里 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="tableData.length"
style="margin-top: 20px; text-align: center;"
/>
<!-- </div> -->
</el-card>
<router-view></router-view>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { getActivityList , changeStatusbyId ,addActivityandtime} from '@/api/manage/activity';
import { ElMessage } from 'element-plus';
import { useactivitytone } from '@/stone/activityStone';
const router = useRouter();
const centerDialogVisible = ref(false);
// 使 ref
const tableData = ref([]);
const activityStone = useactivitytone();
//
const cancel = () => {
centerDialogVisible.value = false;
resetForm();
};
const resetForm = () => {
activity.value = {
activityName: '',
marketOne: '',
marketTwo: '',
status: '',
startTime: '',
endTime: ''
};
}
const addActivityShow = () => {
centerDialogVisible.value = true;
};
//
const addActivity = async () => {
try {
const activityData = {
activityName: activity.value.activityName,
marketOne: activity.value.marketOne,
marketTwo: activity.value.marketTwo,
status: Number(activity.value.status), //
startTime: activity.value.startTime,
endTime: activity.value.endTime
}
const response = await addActivityandtime(activityData)
if (response.code === 200) {
ElMessage.success('活动添加成功')
centerDialogVisible.value = false
fetchActivityList() //
} else {
ElMessage.error(response.message || '活动添加失败')
}
} catch (error) {
console.error('添加活动失败:', error)
ElMessage.error('请求失败,请重试')
}
}
const activity = ref({
activityName: '',
marketOne: '',
marketTwo: '',
status: '',
startTime: '',
endTime: ''
})
//
const currentPage = ref(1);
const pageSize = ref(10); // 10
//
const currentPageData = computed(() => {
const start = (currentPage.value - 1) * pageSize.value;
const end = start + pageSize.value;
return tableData.value.slice(start, end);
});
//
const handleSizeChange = (val) => {
pageSize.value = val;
};
const handleCurrentChange = (val) => {
currentPage.value = val;
};
//
const goToDetail = (row) => {
activityStone.setselectedactivity(row.id);
router.push({ name: 'activityDetail' });
};
const goToSet = () => {
router.push({ name: 'activitySet' });
};
//
const fetchActivityList = async () => {
try {
const response = await getActivityList();
if (response.code === 200) {
tableData.value = response.data.map(item => ({
id: item.id,
activityName: item.activityName,
marketOne: item.marketOne,
marketTwo: item.marketTwo,
status: Number(item.status), // el-switch
startTime: item.startTime,
endTime: item.endTime
}));
} else {
console.error('获取活动列表失败:', response.message);
}
} catch (error) {
console.error('获取活动列表失败:', error);
}
};
const updateStatus = async (row) => {
try {
const response = await changeStatusbyId(row.id, row.status)
if (response.code === 200) {
ElMessage.success('操作成功:修改状态成功')
} else if (response.code === 400) {
ElMessage.error(response.message || '当前有活动正在启用,修改状态失败')
//
row.status = row.status === 1 ? 0 : 1
} else {
ElMessage.error('状态修改失败')
row.status = row.status === 1 ? 0 : 1
}
} catch (error) {
console.error('请求失败:', error)
ElMessage.error('请求失败,请重试')
//
row.status = row.status === 1 ? 0 : 1
}
}
//
onMounted(() => {
fetchActivityList();
});
</script>
<style scoped>
.gray-container {
width: 100%; /* 宽度自适应 */
background-color: #ffffff; /* 浅灰色背景 */
padding: 20px; /* 内边距 */
box-sizing: border-box; /* 包含内边距在总宽度内 */
min-height: 80vh; /* 设置最小高度 */
overflow-x: hidden;
}
.activity-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px; /* 与下方内容的间距 */
}
.header-text {
font-size: 1.5rem;
font-weight: bold;
}
.marginTop {
margin-top: 10px;
}
table {
width: 100%;
border-collapse: collapse;
}
th,
td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
/* 新增样式:让分页控件在 .content-area 内居中显示 */
.content-area {
position: relative;
}
.content-area .el-pagination {
margin-top: 20px;
text-align: center;
}
</style>

179
activitylink/src/views/zhongchou/activity/set/index.vue

@ -0,0 +1,179 @@
<template>
<el-card style="margin-top:50px; min-height: 90vh; max-height: 90vh;">
<div class="data-settings">
<!-- 返回按钮 -->
<br><br><br><br><br>
<el-button type="primary" @click="goBack">
<i class="el-icon-back"></i> 返回
</el-button>
<h3>数据设置</h3>
<div class="setting-item">
<label>设置初始数据</label>
<el-input-number :precision="0" :min="0" v-model="initialData" placeholder="分钟" size="large"></el-input-number>
&nbsp;&nbsp;分钟
&nbsp;&nbsp;&nbsp;&nbsp;
<el-button type="primary" @click="openInitialConfirmDialog">确认</el-button>
</div>
<div class="setting-item">
<label>当前美股助力次数{{ usStockBoostCount }} </label>
<el-input-number :precision="0" :min="0" v-model="usStockAddCount" placeholder="设置添加次数" size="large"></el-input-number>
&nbsp;&nbsp;&nbsp;&nbsp;
<el-button type="primary" @click="openConfirmDialog('us')">确认</el-button>
&nbsp;&nbsp;&nbsp;&nbsp;
<label>前端展示次数{{ usStockDisplayCount }} </label>
</div>
<div class="setting-item">
<label>当前港股助力次数{{ hkStockBoostCount }} </label>
<el-input-number :precision="0" :min="0" v-model="hkStockAddCount" placeholder="设置添加次数" size="large"></el-input-number>
&nbsp;&nbsp;&nbsp;&nbsp;
<el-button type="primary" @click="openConfirmDialog('hk')">确认</el-button>
&nbsp;&nbsp;&nbsp;&nbsp;
<label>前端展示次数{{ hkStockDisplayCount }} </label>
</div>
<!-- 确认对话框 -->
<el-dialog v-model="showConfirmDialog" title="确认添加" width="30%">
<span>您确定要添加这些次数吗</span>
<template #footer>
<span class="dialog-footer">
<el-button @click="showConfirmDialog = false"> </el-button>
<el-button type="primary" @click="confirmAdd"> </el-button>
</span>
</template>
</el-dialog>
<!-- 初始数据确认对话框 -->
<el-dialog v-model="showInitialConfirmDialog" title="确认设置初始数据" width="30%">
<span>您确定要设置初始数据为 {{ initialData }} 分钟吗</span>
<template #footer>
<span class="dialog-footer">
<el-button @click="showInitialConfirmDialog = false"> </el-button>
<el-button type="primary" @click="confirmInitialData"> </el-button>
</span>
</template>
</el-dialog>
</div>
</el-card>
</template>
<script setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
//
const initialData = ref(null);
const usStockBoostCount = ref(234);
const usStockAddCount = ref(null);
const usStockDisplayCount = ref(345);
const hkStockBoostCount = ref(164);
const hkStockAddCount = ref(null);
const hkStockDisplayCount = ref(355);
//
const showConfirmDialog = ref(false);
const showInitialConfirmDialog = ref(false);
const pendingInitialData = ref('');
let pendingAction = ref(null); // ('us' or 'hk')
//
const openConfirmDialog = (type) => {
if ((type === 'us' && usStockAddCount.value) || (type === 'hk' && hkStockAddCount.value)) {
pendingAction.value = type;
showConfirmDialog.value = true;
}
};
//
const openInitialConfirmDialog = () => {
if (initialData.value) {
pendingInitialData.value = initialData.value;
showInitialConfirmDialog.value = true;
}
};
//
const confirmInitialData = () => {
//
console.log('已设置初始数据:', pendingInitialData.value);
//
initialData.value = null;
showInitialConfirmDialog.value = false;
};
//
const confirmAdd = () => {
const type = pendingAction.value;
if (type === 'us') {
usStockBoostCount.value += parseInt(usStockAddCount.value);
usStockDisplayCount.value = usStockBoostCount.value;
usStockAddCount.value = null;
} else if (type === 'hk') {
hkStockBoostCount.value += parseInt(hkStockAddCount.value);
hkStockDisplayCount.value = hkStockBoostCount.value;
hkStockAddCount.value = null;
}
//
pendingAction.value = null;
showConfirmDialog.value = false;
};
//
const goBack = () => {
router.back();
};
</script>
<style scoped>
.data-settings {
background-color: #ffffff;
padding: 40px;
border-radius: 16px;
width: 100%;
max-width: 800px;
margin: 0 auto;
font-size: 1.2rem;
}
.setting-item {
margin-bottom: 25px;
display: flex;
align-items: center;
justify-content: flex-start;
}
.setting-item label {
margin-right: 20px;
font-size: 1.1rem;
}
.setting-item input {
width: 150px;
height: 40px;
font-size: 1.1rem;
text-align: center;
margin-right: 20px;
}
.el-button {
height: 40px;
font-size: 1.1rem;
padding: 0 20px;
}
h3 {
font-size: 1.8rem;
margin-bottom: 20px;
}
</style>

146
activitylink/src/views/zhongchou/gift/importFixedList/index.vue

@ -0,0 +1,146 @@
<template>
<div style="margin-bottom:30px">
<el-button type="primary" @click="goBack" style="margin-right:20px">返回</el-button>
<span style="font-size: 1.5em; font-weight: bold;">导入内定用户</span>
</div>
<el-card style="min-height: 90vh; max-height: 90vh;">
<div style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; gap: 10px; align-items: center;">
<span style="white-space: nowrap;">姓名</span>
<el-input v-model="searchObj.name" placeholder="请输入姓名" style="width: 150px;" clearable></el-input>
<span style="white-space: nowrap; margin-left: 10px;">精网号</span>
<el-input v-model="searchObj.jwcode" placeholder="请输入精网号" style="width: 180px;" clearable
@input="trimJwcode"></el-input>
<el-button type="primary" @click="" style="margin-left: 10px;">搜索</el-button>
</div>
<div style="display: flex; gap: 10px;">
<el-button type="primary" @click="addUser">添加用户</el-button>
<el-button type="success" @click="importExcel">导入Excel</el-button>
</div>
</div>
<!-- 用户表格 -->
<el-table :data="tableData" style="width: 100%;" :row-style="{ height: '60px' }">
<el-table-column type="selection" width="200" />
<el-table-column prop="id" label="ID" width="250" />
<el-table-column prop="name" label="姓名" width="250" />
<el-table-column prop="jwcode" label="精网号" width="300" />
<el-table-column label="操作">
<template #default="scope">
<el-button size="small" type="danger" @click="deleteUser(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 底部操作区域 -->
<div style="margin-top: 20px; display: flex; justify-content: space-between; align-items: center;">
<el-button type="danger" @click="batchDelete">批量删除</el-button>
<div style="display: flex; align-items: center;">
<span style="margin-right: 15px;">{{ total }}</span>
<el-select v-model="pageSize" style="width: 120px; margin-right: 15px;">
<el-option label="10条/页" :value="10" />
<el-option label="20条/页" :value="20" />
<el-option label="50条/页" :value="50" />
</el-select>
<el-pagination layout="prev, pager, next" :total="total" :page-size="pageSize"
v-model:current-page="currentPage" />
<el-input v-model="jumpPage" style="width: 80px; margin-left: 15px; margin-right: 10px;" placeholder="页码" />
<el-button type="primary" @click="goToPage">前往</el-button>
</div>
</div>
</el-card>
<el-dialog v-model="addVisible" title="添加用户" width="500" align-center>
<el-form ref="addForm" :model="winuser" label-width="80px">
<el-form-item label="姓名" prop="name">
<el-input v-model="winuser.name" placeholder="请输入用户姓名" />
</el-form-item>
<el-form-item label="精网号" prop="jwcode">
<el-input v-model="winuser.jwcode" placeholder="请输入精网号" @input="trimJwcode" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="addwinUser">
确定
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { usegiftFixedListStone } from '@/stone/giftFixedListStone';
import { getFixUserList } from '@/api/manage/gift'
const giftStore = usegiftFixedListStone();
const router = useRouter()
const addVisible = ref(false)
const tableData = ref([])
const pagination = ref({
pageNum: 1,
pageSize: 10,
total:0
})
//
const searchObj = ref({
username: '',
jwcode: '',
})
//
const getFixUsers = async () => {
try {
const res = await getFixUserList({
username: searchObj.value.username,
password: searchObj.value.jwcode,
pageNum: pagination.value.pageNum,
pageSize: pagination.value.pageSize
})
if (res.code === 200) {
tableData.value = res.data.list
pagination.value.total = res.data.total
} else {
ElMessage.error(res.message || '获取数据失败')
}
} catch (error) {
console.error('请求失败:', error)
ElMessage.error('请求失败,请重试')
}
}
//
const goToPage = () => {
const page = parseInt(jumpPage.value)
if (!isNaN(page) && page > 0 && page <= Math.ceil(total.value / pageSize.value)) {
currentPage.value = page
}
jumpPage.value = ''
}
const trimJwcode = (value) => {
searchObj.value.jwcode = value.replace(/\D/g, '')
}
//
const goBack = () => {
router.back()
}
onMounted(() => {
getFixUsers()
})
</script>
<style scoped>
.el-card {
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.el-table {
margin-top: 10px;
}
.el-pagination {
margin: 0;
}
</style>

233
activitylink/src/views/zhongchou/gift/importuser/index.vue

@ -0,0 +1,233 @@
<template>
<div style="margin-bottom:30px">
<el-button type="primary" @click="goBack" style="margin-right:20px">返回</el-button>
<span style="font-size: 1.5em; font-weight: bold;">导入抽奖用户</span>
</div>
<el-card>
<div style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center;">
<div>
姓名<el-input v-model="searchObj.username" placeholder="请输入姓名" style="width: 150px;margin-right:10px" clearable></el-input>
精网号<el-input v-model="searchObj.jwcode" placeholder="请输入精网号" style="width: 180px;" clearable @input="trimJwcode"></el-input>
<el-button type="primary" @click="getUsers" style="margin-left: 10px;">搜索</el-button>
</div>
<div style="display: flex; gap: 10px;" fixed:right>
<el-button type="primary" @click="openAdd">添加用户</el-button>
<el-button type="success" @click="importExcel">导入Excel</el-button>
</div>
</div>
<!-- 用户表格 -->
<el-table :data="tableData" style="width: 100%;" :row-style="{ height: '60px' }" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="70" />
<el-table-column type="index" label="ID" width="200" />
<el-table-column prop="username" label="姓名" width="200" />
<el-table-column prop="jwcode" label="精网号" width="200" />
<el-table-column label="操作" fixed="right">
<template #default="scope">
<el-button text type="danger" @click="delUser(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 底部操作区域 -->
<div style="margin-top: 20px; display: flex; justify-content: space-between; align-items: center;">
<el-button text type="danger" @click="batchDelete">批量删除</el-button>
<div style="display: flex; align-items: center;">
<span style="margin-right: 15px;">{{ pagination.total }}</span>
<el-select v-model="pagination.pageSize" style="width: 120px; margin-right: 15px;">
<el-option label="10条/页" :value="10" />
<el-option label="20条/页" :value="20" />
<el-option label="50条/页" :value="50" />
</el-select>
<el-pagination layout="prev, pager, next" :total="pagination.total" :page-size="pagination.pageSize" v-model:current-page="currentPage" />
<el-input v-model="jumpPage" style="width: 80px; margin-left: 15px; margin-right: 10px;" placeholder="页码" />
<el-button type="primary" @click="goToPage">前往</el-button>
</div>
</div>
</el-card>
<el-dialog v-model="addVisible" title="添加用户" width="500" align-center>
<el-form ref="addForm" :model="addObj" label-width="80px">
<el-form-item label="姓名" prop="username">
<el-input v-model="addObj.username" placeholder="请输入用户姓名" />
</el-form-item>
<el-form-item label="精网号" prop="jwcode">
<el-input v-model="addObj.jwcode" placeholder="请输入用户精网号" @input="trimJwcode" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="addVisible = false">取消</el-button>
<el-button type="primary" @click="submitAdd">确定</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { getUserList, addUser, deleteUser, deleteUsers } from '@/api/manage/gift';
import { ElMessage, ElMessageBox } from 'element-plus'
const router = useRouter()
const addVisible = ref(false)
const tableData = ref([])
// id
const selectedIds = ref([])
//
const searchObj = ref({
username: '',
jwcode: '',
})
const addObj = ref({
username: '',
jwcode: '',
})
const pagination = ref({
pageNum: 1,
pageSize: 10,
total:0
})
const openAdd = () => {
addObj.value = {}
addVisible.value = true
}
//
const getUsers = async () => {
try {
const res = await getUserList({
username: searchObj.value.username,
jwcode: searchObj.value.jwcode,
pageNum: pagination.value.pageNum,
pageSize: pagination.value.pageSize
})
if (res.code === 200) {
tableData.value = res.data.list
pagination.value.total = res.data.total
} else {
ElMessage.error(res.message || '获取数据失败')
}
} catch (error) {
console.error('请求失败:', error)
ElMessage.error('请求失败,请重试')
}
}
//
const submitAdd = async () => {
if (!addObj.value.username || addObj.value.jwcode === '') {
ElMessage.error('请填写完整信息')
return
}
try {
const data = {
username: addObj.value.username,
jwcode: addObj.value.jwcode
}
console.log('看看添加参数',data)
const response = await addUser(data)
if (response.code === 200) {
ElMessage.success('添加成功')
addVisible.value = false
getUsers()
} else {
ElMessage.error(response.message || '添加失败')
}
} catch (error) {
console.error('添加等级失败:', error)
ElMessage.error('添加失败,请重试')
}
}
//
const delUser = (row) => {
ElMessageBox.confirm('确定要删除该用户吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
try {
const id = String(row.id)
console.log('删除等级的id是:', id)
const response = await deleteUser(id)
if (response.code === 200) {
ElMessage.success('删除成功')
getUsers()
} else {
ElMessage.error(response.message || '删除失败')
}
} catch (error) {
console.error('删除失败:', error)
ElMessage.error('删除失败,请重试')
}
}).catch(() => {
ElMessage.info('已取消删除')
})
}
//
const batchDelete = async () => {
if (selectedIds.value.length === 0) {
ElMessage.warning('请先选择需要删除的用户')
return
}
ElMessageBox.confirm(`确定要删除选中的${selectedIds.value.length}条数据吗?`,// $??
'删除确认',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(async () => {
try {
const response = await deleteUsers(selectedIds.value.join(','))
console.log(selectedIds.value.join(','))
if (response.code === 200) {
ElMessage.success('批量删除成功')
getUsers()
selectedIds.value = []
} else {
ElMessage.error(response.message || '批量删除失败')
}
} catch (error) {
console.error('批量删除请求失败:', error)
ElMessage.error('网络错误,批量删除失败')
}
}).catch(() => {
ElMessage.info('已取消批量删除')
})
}
const goBack = () => {
router.back()
}
//
const goToPage = () => {
const page = parseInt(jumpPage.value)
if (!isNaN(page) && page > 0 && page <= Math.ceil(total.value / pageSize.value)) {
currentPage.value = page
}
jumpPage.value = ''
}
const handleSelectionChange = (selection) => {
// id
selectedIds.value = selection.map(row => row.id)
}
const trimJwcode = (value) => {
searchObj.value.jwcode = value.replace(/\D/g, '')
}
onMounted(() => {
getUsers()
})
</script>
<style scoped>
.el-card {
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.el-table {
margin-top: 10px;
}
.el-pagination {
margin: 0;
}
</style>

416
activitylink/src/views/zhongchou/gift/index.vue

@ -0,0 +1,416 @@
<template>
<h2>礼品管理</h2>
<el-card style="min-height: 90vh; max-height: 90vh; display: flex; flex-direction: column;">
<div class="gift-management-container" style="flex: 1; overflow-y: auto;">
<div class="action-buttons">
<el-button type="primary" @click="showAdd">添加礼品</el-button>
<el-button type="primary" @click="goToimportUsers">导入抽奖用户</el-button>
</div>
<div class="table-container" style="flex: 1; overflow-y: auto;">
<el-table :data="tableData" style="width: 100%" class="gift-table">
<el-table-column type="index" label="ID" width="100" align="center"></el-table-column>
<el-table-column label="礼品图片" width="200" align="center">
<template #default="scope">
<img v-if="scope.row.imageUrl" :src="scope.row.imageUrl"
style="max-width: 100px; max-height: 30px;">
<el-icon v-else :size="20" color="#67C23A">
<Check />
</el-icon>
</template>
</el-table-column>
<el-table-column prop="prizeName" label="名称" width="300" align="center"></el-table-column>
<el-table-column prop="gradeName" label="等级" width="200" align="center"></el-table-column>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button type="primary" text @click="goToimportFixedList(scope.row)">导入内定名单</el-button>
<el-button type="warning" text @click="editGift(scope.row)">编辑</el-button>
<el-button type="danger" text @click="deleteGift(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<el-pagination class="pagination" v-model:current-page="pagination.pageNum" v-model:page-size="pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" :page-sizes="[10, 20, 50, 100]"
@size-change="handleSizeChange" @current-change="handleCurrentChange">
</el-pagination>
<!-- 添加 -->
<el-dialog v-model="addVisible" :title="dialogTitle" width="40%">
<el-form :model="addForm" label-width="100px" ref="formRef">
<el-form-item label="礼品名称" :rules="{ required: true, message: '请输入礼品名称', trigger: 'blur' }">
<el-input v-model="addForm.prizeName" placeholder="请输入礼品名称"></el-input>
</el-form-item>
<el-form-item label="礼品等级" :rules="{ required: true, message: '请选择礼品等级', trigger: 'change' }">
<el-select v-model="addForm.gradeId" placeholder="请选择礼品等级">
<el-option v-for="item in gradeNames" :key="item.id" :label="item.gradeName" :value="item.id"/>
</el-select>
</el-form-item>
<el-form-item label="礼品图片" :rules="{ required: true, message: '请上传图片', trigger: 'change' }">
<el-upload
ref="uploadRef"
:action="uploadUrl"
list-type="picture-card"
:auto-upload="false"
:on-change="handleImageChange"
:on-success="handleUploadSuccess"
:on-error="handleUploadError"
:before-upload="beforeUpload"
:show-file-list="false">
<el-icon>
<Plus />
</el-icon>
<template #tip>
<div class="el-upload__tip">
只能上传jpgpng格式的图片且不超过500KB
</div>
</template>
</el-upload>
<div v-if="addForm.imageUrl" class="upload-preview">
<img :src="addForm.imageUrl" alt="预览图" style="max-width: 200px; margin-top: 10px; border-radius: 4px;">
</div>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="addVisible = false">取消</el-button>
<el-button type="primary" @click="submitAdd">确认</el-button>
</span>
</template>
</el-dialog>
<!-- 编辑 -->
<el-dialog v-model="editVisible" :title="dialogTitle" width="40%">
<el-form :model="editForm" label-width="100px" ref="formRef">
<el-form-item label="礼品名称" :rules="{ required: true, message: '请输入礼品名称', trigger: 'blur' }">
<el-input v-model="editForm.prizeName" placeholder="请输入礼品名称"></el-input>
</el-form-item>
<el-form-item label="礼品等级" :rules="{ required: true, message: '请选择礼品等级', trigger: 'change' }">
<el-select v-model="editForm.gradeId" placeholder="请选择礼品等级">
<el-option v-for="item in gradeNames" :key="item.id" :label="item.gradeName" :value="item.id"/>
</el-select>
</el-form-item>
<el-form-item label="礼品图片" :rules="{ required: true, message: '请上传图片', trigger: 'change' }">
<el-upload
ref="uploadRef"
:action="uploadUrl"
list-type="picture-card"
:auto-upload="false"
:on-change="handleImageChange"
:on-success="handleUploadSuccess"
:on-error="handleUploadError"
:before-upload="beforeUpload"
:show-file-list="false">
<el-icon>
<Plus />
</el-icon>
<template #tip>
<div class="el-upload__tip">
只能上传jpgpng格式的图片且不超过500KB
</div>
</template>
</el-upload>
<div v-if="editForm.imageUrl" class="upload-preview">
<img :src="editForm.imageUrl" alt="预览图" style="max-width: 200px; margin-top: 10px; border-radius: 4px;">
</div>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="editVisible = false">取消</el-button>
<el-button type="primary" @click="submitEdit">确认</el-button>
</span>
</template>
</el-dialog>
</el-card>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import { Check, Plus } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useRouter } from 'vue-router';
import { usegiftFixedListStone } from '@/stone/giftFixedListStone';
import { getPrizeList, addPrize, deletePrize, updatePrize } from '@/api/manage/gift';
import { getGradeNameList } from '@/api/manage/level';
const router = useRouter();
const gradeNames = ref([])
const tableData = ref([])
const giftStore = usegiftFixedListStone();
const pagination = ref({
pageNum: 1,
pageSize: 10,
total: 0
})
const addVisible = ref(false)
const editVisible = ref(false)
const dialogTitle = ref('添加礼品')
const addForm = ref({
prizeName: '',
gradeId: '',
imageUrl: null
})
const editForm = ref({
prizeName: '',
gradeId: '',
imageUrl: null
})
const uploadUrl = 'http://39.101.133.168:8828/hljw/api/aws/upload';
const formRef = ref(null)
const uploadRef = ref(null)
const showAdd = () => {
dialogTitle.value = '添加礼品'
addForm.value = {
prizeName: '',
gradeId: '',
imageUrl: null
}
addVisible.value = true
}
const editGift = (row) => {
dialogTitle.value = '编辑礼品'
editForm.value = {
id: row.id,
prizeName: row.prizeName,
gradeId: row.gradeId,
imageUrl: row.imageUrl
}
editVisible.value = true
}
//
const getPrizes = async () => {
try {
const res = await getPrizeList({
pageNum: pagination.value.pageNum,
pageSize: pagination.value.pageSize
})
if (res.code === 200) {
tableData.value = res.data.list
pagination.value.total = res.data.total
} else {
ElMessage.error(res.message || '获取数据失败')
}
} catch (error) {
console.error('请求失败:', error)
ElMessage.error('请求失败,请重试')
}
}
//
const getGradeNames = async () => {
try {
const res = await getGradeNameList()
if (res.code === 200) {
gradeNames.value = res.data
} else {
ElMessage.error(res.message || '获取下拉框失败')
}
} catch (error) {
console.error('获取下拉框失败:', error)
ElMessage.error('获取下拉框失败')
}
}
//
const submitAdd = async () => {
formRef.value.validate((valid) => {
if (!valid) return false;
if (!addForm.value.imageUrl) {
ElMessage.error('请上传图片');
return;
}
try {
const data = {
prizeName: addForm.value.prizeName,
gradeId: String(addForm.value.gradeId),
imageUrl: addForm.value.imageUrl
}
console.log('添加参数:', data)
addPrize(data).then(response => {
if (response.code === 200) {
ElMessage.success('添加成功')
addVisible.value = false
getPrizes()
} else {
ElMessage.error(response.message || '添加失败')
}
}).catch(error => {
console.error('添加失败:', error)
ElMessage.error('添加失败,请重试')
})
} catch (error) {
console.error('添加失败:', error)
ElMessage.error('添加失败,请重试')
}
});
}
//
const deleteGift = (row) => {
ElMessageBox.confirm('确定要删除该等级吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
try {
const id = String(row.id)
console.log('删除礼品的id是:', id)
const response = await deletePrize(id)
if (response.code === 200) {
ElMessage.success('删除成功')
getPrizes()
} else {
ElMessage.error(response.message || '删除失败')
}
} catch (error) {
console.error('删除失败:', error)
ElMessage.error('删除失败,请重试')
}
}).catch(() => {
ElMessage.info('已取消删除')
})
}
//
const submitEdit = async () => {
formRef.value.validate((valid) => {
if (!valid) return false;
if (!editForm.value.imageUrl) {
ElMessage.error('请上传图片');
return;
}
try {
const data = {
id: editForm.value.id,
prizeName: editForm.value.prizeName,
gradeId: String(editForm.value.gradeId),
imageUrl: editForm.value.imageUrl
}
console.log('添加参数:', data)
updatePrize(data).then(response => {
if (response.code === 200) {
ElMessage.success('编辑成功')
editVisible.value = false
getPrizes()
} else {
ElMessage.error(response.message || '编辑失败')
}
})
} catch (error) {
console.error('编辑失败:', error)
ElMessage.error('编辑失败,请重试')
}
});
}
const goToimportFixedList = (row) => {
giftStore.setFixedGiftName(row.name);
router.push({ name: 'importFixedList' });
}
const goToimportUsers = () => {
router.push({ name: 'importUsers' });
}
const handleImageChange = (file) => {
uploadRef.value.submit();
}
const handleUploadSuccess = (response, file, fileList) => {
if (response.code === 200) {
if (addVisible.value) {
addForm.value.imageUrl = response.data.url;
} else if (editVisible.value) {
editForm.value.imageUrl = response.data.url;
}
ElMessage.success('图片上传成功');
} else {
if (addVisible.value) {
addForm.value.imageUrl = null;
} else if (editVisible.value) {
editForm.value.imageUrl = null;
}
ElMessage.error(response.message || '图片上传失败');
}
}
const handleUploadError = (error) => {
console.error('上传失败:', error);
if (addVisible.value) {
addForm.value.imageUrl = null;
} else if (editVisible.value) {
editForm.value.imageUrl = null;
}
ElMessage.error('图片上传失败,请重试');
}
const beforeUpload = (file) => {
const isJPG = file.type === 'image/jpeg';
const isPNG = file.type === 'image/png';
const isLt500K = file.size / 1024 < 500;
if (!isJPG && !isPNG) {
ElMessage.error('上传图片只能是 JPG 或 PNG 格式!');
return false;
}
if (!isLt500K) {
ElMessage.error('上传图片大小不能超过 500KB!');
return false;
}
return true;
}
const handleSizeChange = (val) => {
pagination.value.pageSize = val
pagination.value.pageNum = 1
}
const handleCurrentChange = (val) => {
pagination.value.pageNum = val
}
onMounted(() => {
getPrizes()
getGradeNames()
})
</script>
<style scoped>
.gift-management-container {
padding: 20px;
width: 100%;
box-sizing: border-box;
min-height: 80vh;
}
.pagination-container {
padding: 10px 20px;
background-color: #fff;
border-top: 1px solid #ebeef5;
display: flex;
justify-content: center;
}
.action-buttons {
margin-bottom: 20px;
}
.table-container {
max-height: 600px;
overflow-y: auto;
}
/* 添加图片样式 */
img {
max-height: 80px;
object-fit: contain;
border-radius: 4px;
}
.upload-preview {
margin-top: 10px;
}
</style>

101
activitylink/src/views/zhongchou/index.vue

@ -0,0 +1,101 @@
<script setup>
import {
Promotion,
Location,
Menu as IconMenu,
Document,
Setting
} from '@element-plus/icons-vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const handleOpen = (key, keyPath) => {
// console.log(':', key, keyPath)
}
const handleClose = (key, keyPath) => {
// console.log(':', key, keyPath)
}
</script>
<template>
<div class="common-layout">
<el-container class="el-container">
<!-- 左侧菜单 -->
<el-aside class="aside">
<el-menu
active-text-color="#ffd04b"
background-color="#545c64"
class="el-menu-vertical-demo"
default-active="/index"
text-color="#fff"
@open="handleOpen"
@close="handleClose"
style="height: 100%;"
router
>
<el-menu-item index="/zhongchou/mainimg" >
<el-icon><Promotion /></el-icon>
<span>后台管理系统</span>
</el-menu-item>
<el-menu-item index="/zhongchou/levelManagement" >
<el-icon><location /></el-icon>
<span>等级管理</span>
</el-menu-item>
<el-menu-item index="/zhongchou/giftManagement" >
<el-icon><icon-menu /></el-icon>
<span>礼品管理</span>
</el-menu-item>
<el-menu-item index="/zhongchou/winningManagement">
<el-icon><document /></el-icon>
<span>中奖管理</span>
</el-menu-item>
<el-menu-item index="/zhongchou/activityManagement">
<el-icon><setting /></el-icon>
<span>众筹活动</span>
</el-menu-item>
</el-menu>
</el-aside>
<el-main class="el-main">
<router-view></router-view>
</el-main>
</el-container>
</div>
</template>
<style scoped>
a {
color: white;
text-decoration: none;
}
.aside {
width: 220px;
border-right: 1px solid #ccc;
min-height: 100vh;
}
.common-layout {
height: 100vh;
overflow: hidden;
width: 100vw;
}
.el-container {
display: flex;
flex-direction: row;
height: 100%;
}
.el-main {
flex: 1; /* 关键:自动撑满剩余空间 */
padding: 20px;
overflow: auto;
}
</style>

279
activitylink/src/views/zhongchou/level/index.vue

@ -0,0 +1,279 @@
<template>
<h2>等级管理</h2>
<el-card style="min-height: 90vh; max-height: 90vh; display: flex; flex-direction: column;">
<div class="level-management-container" style="flex: 1; overflow-y: auto;">
<!-- 添加等级按钮 -->
<div class="action-buttons">
<el-button type="primary" @click="showAddDialog">添加等级</el-button>
</div>
<!-- 等级表格 -->
<div class="table-container">
<el-table :data="tableData" style="width: 100%" :row-style="{ height: '55px' }">
<el-table-column type="index" label="ID" width="100px" fixed="left" />
<el-table-column prop="gradeName" label="等级名称" width="200" align="center" />
<el-table-column prop="amount" label="数量" width="250" align="center" />
<el-table-column prop="perWin" label="每轮抽取人数" width="300" align="center" />
<el-table-column prop="sort" label="排序" width="200" align="center" />
<el-table-column prop="operation" fixed="right" label="操作" align="center">
<template #default="scope">
<div style="display: flex; gap: 10px; justify-content: center;">
<el-button text type="warning" @click="editLevel(scope.row)">编辑</el-button>
<el-button text type="danger" @click="deleteLevel(scope.row)">删除</el-button>
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
<!-- 分页 -->
<el-pagination class="pagination" v-model:current-page="pagination.pageNum" v-model:page-size="pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" :page-sizes="[10, 20, 50, 100]"
@size-change="handleSizeChange" @current-change="handleCurrentChange" />
<!-- 添加 -->
<el-dialog v-model="addVisible" :title="dialogTitle" width=400px @closed="resetForm">
<el-form :model="addForm" label-width="120px">
<el-form-item label="等级名称" align="center">
<el-input v-model="addForm.gradeName" placeholder="请输入等级名称"></el-input>
</el-form-item>
<el-form-item label="数量" align="center">
<el-input v-model="addForm.amount" :precision="0" :min="0" placeholder="请输入数量"
style="width: 100%;"></el-input>
</el-form-item>
<el-form-item label="每轮抽取人数" align="center">
<el-input v-model="addForm.perWin" :precision="0" :min="0" placeholder="请输入抽取人数"
style="width: 100%;"></el-input>
</el-form-item>
<el-form-item label="排序" align="center">
<el-input v-model="addForm.sort" :precision="0" :min="0" placeholder="请输入排序等级"
style="width: 100%;"></el-input>
</el-form-item>
</el-form>
<template #footer>
<span>
<el-button @click="addVisible = false">取消</el-button>
<el-button type="primary" @click="submitAdd">确认</el-button>
</span>
</template>
</el-dialog>
<!-- 编辑 -->
<el-dialog v-model="editVisible" :title="dialogTitle" width=400px @closed="resetForm">
<el-form :model="editForm" label-width="120px">
<el-form-item label="等级名称" align="center">
<el-input v-model="editForm.gradeName" placeholder="请输入等级名称"></el-input>
</el-form-item>
<el-form-item label="数量" align="center">
<el-input v-model="editForm.amount" :precision="0" :min="0" placeholder="请输入数量"
style="width: 100%;"></el-input>
</el-form-item>
<el-form-item label="每轮抽取人数" align="center">
<el-input v-model="editForm.perWin" :precision="0" :min="0" placeholder="请输入抽取人数"
style="width: 100%;"></el-input>
</el-form-item>
<el-form-item label="排序" align="center">
<el-input v-model="editForm.sort" :precision="0" :min="0" placeholder="请输入排序等级"
style="width: 100%;"></el-input>
</el-form-item>
</el-form>
<template #footer>
<span>
<el-button @click="editVisible = false">取消</el-button>
<el-button type="primary" @click="submitEdit">确认</el-button>
</span>
</template>
</el-dialog>
</el-card>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getLevelList, addLevel, deleteGrade, updateGrade } from '@/api/manage/level'
const tableData = ref([])
const pagination = ref({
pageNum: 1,
pageSize: 10,
total:0
})
const addVisible = ref(false)
const editVisible = ref(false)
const dialogTitle = ref('')
const addForm = ref({
gradeName: '',
amount: '',
perWin: '',
sort: ''
})
const editForm = ref({})
//
const showAddDialog = () => {
dialogTitle.value = '添加等级'
addVisible.value = true
}
//
const editLevel = (row) => {
dialogTitle.value = '编辑等级'
editForm.value = {
id: row.id,
gradeName: row.gradeName,
amount: row.amount,
perWin: row.perWin,
sort: row.sort
}
editVisible.value = true
}
//
const getLevels = async () => {
try {
const res = await getLevelList({
pageNum: pagination.value.pageNum,
pageSize: pagination.value.pageSize
})
if (res.code === 200) {
tableData.value = res.data.list
pagination.value.total = res.data.total
} else {
ElMessage.error(res.message || '获取数据失败')
}
} catch (error) {
console.error('请求失败:', error)
ElMessage.error('请求失败,请重试')
}
}
//
const submitAdd = async () => {
if (!addForm.value.gradeName || addForm.value.amount === '' || addForm.value.sort === '' || addForm.value.perWin === '') {
ElMessage.error('请填写完整信息')
return
}
try {
const data = {
gradeName: String(addForm.value.gradeName),
amount: String(addForm.value.amount),
sort: String(addForm.value.sort),
perWin: String(addForm.value.perWin)
}
console.log('看看添加参数',data)
const response = await addLevel(data)
if (response.code === 200) {
ElMessage.success('添加成功')
addVisible.value = false
getLevels()
} else {
ElMessage.error(response.message || '添加失败')
}
} catch (error) {
console.error('添加等级失败:', error)
ElMessage.error('添加失败,请重试')
}
}
//
const submitEdit = async () => {
if (!editForm.value.id || !editForm.value.gradeName || !editForm.value.amount || !editForm.value.perWin || !editForm.value.sort) {
ElMessage.error('请填写完整信息')
return
}
try {
const editData = {
id: editForm.value.id,
gradeName: editForm.value.gradeName,
amount: editForm.value.amount,
perWin: editForm.value.perWin,
sort: editForm.value.sort
}
console.log('看看编辑参数',editData)
const response = await updateGrade(editData)
if (response.code === 200) {
ElMessage.success('修改成功')
editVisible.value = false
getLevels()
} else {
ElMessage.error(response.message || '修改失败')
}
} catch (error) {
console.error('编辑等级失败:', error)
ElMessage.error('修改失败,请重试')
}
}
//
const deleteLevel = (row) => {
ElMessageBox.confirm('确定要删除该等级吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
try {
const id = String(row.id)
console.log('删除等级的id是:', id)
const response = await deleteGrade(id)
if (response.code === 200) {
ElMessage.success('删除成功')
getLevels()
} else {
ElMessage.error(response.message || '删除失败')
}
} catch (error) {
console.error('删除失败:', error)
ElMessage.error('删除失败,请重试')
}
}).catch(() => {
ElMessage.info('已取消删除')
})
}
//
const resetForm = () => {
addForm.value = {
gradeName: '',
amount: '',
perWin: '',
sort: ''
}
}
const handleSizeChange = (val) => {
pagination.value.pageSize = val
pagination.value.pageNum = 1
getLevels()
}
const handleCurrentChange = (val) => {
pagination.value.pageNum = val
getLevels()
}
onMounted(() => {
getLevels()
})
</script>
<style scoped>
.level-management-container {
padding: 20px;
width: 100%;
box-sizing: border-box;
min-height: 80vh;
}
.pagination {
padding: 10px 20px;
background-color: #fff;
border-top: 1px solid #ebeef5;
display: flex;
justify-content: flex-start;
/* 改为左对齐 */
}
.action-buttons {
margin-bottom: 20px;
}
.table-container {
max-height: 600px;
overflow-y: auto;
}
</style>

35
activitylink/src/views/zhongchou/mainImg/DefaultImage.vue

@ -0,0 +1,35 @@
<template>
<div class="default-image-container">
<div class="default-image"></div>
</div>
</template>
<script setup>
//
</script>
<style scoped>
.default-image-container {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
z-index: -1; /* 放在其他内容之后 */
}
.default-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url('@/img/1.jpg') no-repeat center center fixed;
background-size: cover;
background-position: center;
z-index: -1;
}
</style>

255
activitylink/src/views/zhongchou/winning/index.vue

@ -0,0 +1,255 @@
<!-- 0特等奖 1一等奖 以此类推 -->
<template>
<el-card style="margin-top: 50px ; min-height: 90vh; max-height: 90vh;">
<!-- 返回按钮 -->
<!-- 搜索栏 -->
<div class="gray-container">
<h2>中奖管理</h2>
<el-form :inline="true" class="search-bar">
<el-form-item label="姓名">
<el-input v-model="searchData.name" placeholder="请输入姓名"></el-input>
</el-form-item>
<el-form-item label="精网号">
<el-input
v-model="searchData.jingwangId"
placeholder="请输入精网号"
@input="handleJingwangIdInput"
></el-input>
</el-form-item>
<el-form-item label="中奖等级">
<el-select v-model="searchData.prizeLevel" placeholder="请选择" class="prize-level-select">
<el-option label="全部" value=""></el-option>
<el-option label="特等奖" value="0"></el-option>
<el-option label="一等奖" value="1"></el-option>
<!-- 其他选项... -->
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary">搜索</el-button>
</el-form-item>
<el-form-item>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleExport">导出数据</el-button>
</el-form-item>
</el-form>
<!-- 表格 -->
<div class="table-container">
<el-table :data="currentPageData" style="width: 100%" :row-style="{ height: '55px' }">
<el-table-column prop="id" label="ID" width="100" align="center"></el-table-column>
<el-table-column prop="name" label="姓名" width="180" align="center"></el-table-column>
<el-table-column prop="jingwangId" label="精网号" width="250" align="center"></el-table-column>
<!-- <el-table-column prop="prizeLevel" label="中奖等级" width="200" align="center"></el-table-column> -->
<el-table-column label="中奖等级" width="200" align="center">
<template #default="scope">
<span v-if="scope.row.prizeLevel == '0' ">特等奖</span>
<span v-if="scope.row.prizeLevel == '1' ">一等奖</span>
<span v-if="scope.row.prizeLevel == '2' ">二等奖</span>
<span v-if="scope.row.prizeLevel == '3' ">三等奖</span>
</template>
</el-table-column>
<el-table-column prop="prizeItem" label="所中礼品" width="300" align="center"></el-table-column>
<el-table-column prop="prizeTime" label="中奖时间" align="center"></el-table-column>
</el-table>
</div>
</div>
<!-- 分页 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="tableData.length"
>
</el-pagination>
</el-card>
</template>
<script setup>
import { ref, computed } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
//
const searchData = ref({
name: '',
jingwangId: '',
prizeLevel: ''
})
const tableData = ref([
{
id: 1,
name: '张家伟',
jingwangId: '90047666',
prizeLevel: '0',
prizeItem: 'zimomo',
prizeTime: '2025-07-12 14:05:30'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666',
prizeLevel: '0',
prizeItem: 'zimomo',
prizeTime: '2025-07-12 14:05:30'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666',
prizeLevel: '0',
prizeItem: 'zimomo',
prizeTime: '2025-07-12 14:05:30'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666',
prizeLevel: '0',
prizeItem: 'zimomo',
prizeTime: '2025-07-12 14:05:30'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666',
prizeLevel: '0',
prizeItem: 'zimomo',
prizeTime: '2025-07-12 14:05:30'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666',
prizeLevel: '0',
prizeItem: 'zimomo',
prizeTime: '2025-07-12 14:05:30'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666',
prizeLevel: '0',
prizeItem: 'zimomo',
prizeTime: '2025-07-12 14:05:30'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666',
prizeLevel: '0',
prizeItem: 'zimomo',
prizeTime: '2025-07-12 14:05:30'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666',
prizeLevel: '0',
prizeItem: 'zimomo',
prizeTime: '2025-07-12 14:05:30'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666',
prizeLevel: '0',
prizeItem: 'zimomo',
prizeTime: '2025-07-12 14:05:30'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666',
prizeLevel: '0',
prizeItem: 'zimomo',
prizeTime: '2025-07-12 14:05:30'
},
// ...
])
const currentPage = ref(1)
const pageSize = ref(10)
//
const currentPageData = computed(() => {
const start = (currentPage.value - 1) * pageSize.value
const end = start + pageSize.value
return tableData.value.slice(start, end)
})
// const currentPageData = computed(() => {
// const start = (currentPage.value - 1) * pageSize.value
// const end = start + pageSize.value
// return tableData.value.slice(start, end)
// })
//
const goBack = () => {
router.back()
}
//
const handleExport = () => {
console.log('Export Data')
}
// size
const handleSizeChange = (val) => {
pageSize.value = val
currentPage.value = 1
}
//
const handleCurrentChange = (val) => {
currentPage.value = val
}
//
const handleJingwangIdInput = (value) => {
searchData.value.jingwangId = value.replace(/\D/g, '')
}
//
const handleReset = () => {
searchData.value = {
name: '',
jingwangId: '',
prizeLevel: ''
}
}
</script>
<style scoped>
.info-bar {
margin: 10px 0;
font-size: 16px;
}
.search-bar {
margin-bottom: 20px;
}
.prize-level-select {
width: 200px; /* 调整中奖等级选择框的宽度 */
}
.table-container {
height: 600px; /* 根据需要调整高度 */
overflow-y: auto; /* 启用垂直滚动条 */
}
.gray-container {
width: 100%; /* 宽度自适应 */
background-color: #ffffff; /* 浅灰色背景 */
padding: 20px; /* 内边距 */
box-sizing: border-box; /* 包含内边距在总宽度内 */
min-height: 80vh; /* 设置最小高度 */
overflow-x: hidden;
}
</style>

24
activitylink/vite.config.js

@ -0,0 +1,24 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
},
server: {
proxy: {
'/admin': {
target: 'http://localhost:12699', // 后端基础地址https://dbqb.nfdxy.net/devLotApi
changeOrigin: true,
rewrite: (path) => path
// 或者更精确的重写(根据后端路径调整):.replace(/^\/api/, '')
// rewrite: (path) => path.replace(/^\/api\/admin/, '/admin'),
},
},
},
})
Loading…
Cancel
Save