Browse Source

存"

lihuilin/feature-20250718094329-25周年庆后台
wangxiangwen4 4 weeks ago
parent
commit
e97fe769c3
  1. 13
      .env.development
  2. 20
      .env.production
  3. 24
      .gitignore
  4. 3
      .vscode/extensions.json
  5. 15
      activitylink/.env.development
  6. 19
      activitylink/.env.production
  7. 2
      activitylink/index.html
  8. 1403
      activitylink/package-lock.json
  9. 1
      activitylink/src/api/manage/activity.js
  10. 24
      activitylink/src/api/manage/gift.js
  11. 1
      activitylink/src/api/manage/level.js
  12. 0
      activitylink/src/global.d.ts
  13. 7
      activitylink/src/router/index.js
  14. 2
      activitylink/src/views/zhongchou/gift/index.vue
  15. 347
      activitylink/src/views/zhongchou/level/index.vue
  16. 37
      activitylink/vite.config.js
  17. 13
      index.html
  18. 2262
      package-lock.json
  19. 20
      package.json
  20. 1
      public/vite.svg
  21. 9
      src/App.vue
  22. 4
      src/api/API.js
  23. 1
      src/assets/vue.svg
  24. BIN
      src/img/image.png
  25. 17
      src/main.js
  26. 74
      src/router/index.js
  27. 21
      src/stone/counter.js
  28. 26
      src/stone/giftFixedListStone.js
  29. 79
      src/style.css
  30. 130
      src/utils/request.js
  31. 0
      src/views/choujiang/index.vue
  32. 17
      src/views/homePage.vue
  33. 282
      src/views/zhongchou/activity/detail/index.vue
  34. 242
      src/views/zhongchou/activity/index.vue
  35. 179
      src/views/zhongchou/activity/set/index.vue
  36. 272
      src/views/zhongchou/gift/importFixedList/index.vue
  37. 266
      src/views/zhongchou/gift/importuser/index.vue
  38. 246
      src/views/zhongchou/gift/index.vue
  39. 128
      src/views/zhongchou/index.vue
  40. 274
      src/views/zhongchou/level/index.vue
  41. 251
      src/views/zhongchou/winning/index.vue
  42. 14
      vite.config.js

13
.env.development

@ -0,0 +1,13 @@
# must start with VITE_
VITE_ENV = 'development'
VITE_OUTPUT_DIR = 'dev'
# public path
VITE_PUBLIC_PATH = /
#新数据接口
# VITE_APP_API_BASE_URL = "http://39.101.133.168:8828/link"
# Whether to open mock
VITE_USE_MOCK = true

20
.env.production

@ -0,0 +1,20 @@
# 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
# Whether to enable gzip or brotli compression
# Optional: gzip | brotli | none
# If you need multiple forms, you can use `,` to separate
VITE_BUILD_COMPRESS = 'none'
# Whether to delete origin files when using compress, default false
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false

24
.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
.vscode/extensions.json

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

15
activitylink/.env.development

@ -1,15 +1,6 @@
# must start with VITE_
VITE_ENV = 'development' VITE_ENV = 'development'
VITE_OUTPUT_DIR = 'dev' VITE_OUTPUT_DIR = 'dev'
# public path
VITE_PUBLIC_PATH = /
#新数据接口
# VITE_APP_API_BASE_URL = "http://39.101.133.168:8828/link"
# VITE_APP_BASE_API = 'http://47.92.148.30:3003/mock/3267'
# VITE_APP_BASE_API = 'http://39.98.127.73/price'
VITE_APP_BASE_API = '/api'
# Whether to open mock
VITE_PUBLIC_PATH = '/testBack/'
VITE_APP_BASE_API = 'https://dbqb.nfdxy.net/devLotApi/'
VITE_USE_MOCK = true VITE_USE_MOCK = true
VITE_UPLOAD_URL=http://39.101.133.168:8828/hljw/api/aws/upload

19
activitylink/.env.production

@ -1,20 +1,7 @@
# must start with VITE_
VITE_ENV = 'production' VITE_ENV = 'production'
VITE_OUTPUT_DIR = 'dist' VITE_OUTPUT_DIR = 'dist'
# public path
VITE_PUBLIC_PATH = /aixiaocaishen
# VITE_PUBLIC_PATH = /
# Whether to open mock
VITE_PUBLIC_PATH = '/testBack/'
VITE_USE_MOCK = true VITE_USE_MOCK = true
#新数据接口
# VITE_APP_API_BASE_URL = https://api.homilychart.com/link
# Whether to enable gzip or brotli compression
# Optional: gzip | brotli | none
# If you need multiple forms, you can use `,` to separate
VITE_BUILD_COMPRESS = 'none' VITE_BUILD_COMPRESS = 'none'
# Whether to delete origin files when using compress, default false
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
VITE_APP_BASE_API = 'https://dbqb.nfdxy.net/devLotApi/'

2
activitylink/index.html

@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue</title>
<title>周年庆后台 V1.0</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

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

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

@ -1,5 +1,6 @@
import request from '@/utils/request' import request from '@/utils/request'
export function getActivityList() { export function getActivityList() {
return request({ return request({
url: '/admin/funding/getActivity', url: '/admin/funding/getActivity',

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

@ -1,8 +1,28 @@
import request from '@/utils/request' import request from '@/utils/request'
const baseUrl = import.meta.env.VITE_APP_BASE_API
//奖品新增 //奖品新增
export function addPrize(data) { export function addPrize(data) {
return request({ return request({
url: baseUrl+'/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/add', url: '/admin/prize/add',
method: 'post', method: 'post',
data: data, data: data,
@ -17,7 +37,7 @@ export function deletePrize(id) {
return request({ return request({
url: '/admin/prize/delete', url: '/admin/prize/delete',
method: 'post', method: 'post',
params: { pageNum,pageSize }
params: params
}) })
} }
//奖品分页查询 //奖品分页查询

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

@ -1,5 +1,6 @@
import request from '@/utils/request' import request from '@/utils/request'
const baseUrl = import.meta.env.VITE_APP_BASE_API
// 等级查询 // 等级查询
export function getLevelList(params) { export function getLevelList(params) {
return request({ return request({

0
activitylink/src/global.d.ts

7
activitylink/src/router/index.js

@ -13,11 +13,6 @@ const routes = [
// ] // ]
}, },
{ {
path: '/choujiang',
name: 'choujiang',
component: () => import('../views/choujiang/index.vue'),
},
{
path: '/zhongchou', path: '/zhongchou',
name: 'zhongchou', name: 'zhongchou',
component: () => import('../views/zhongchou/index.vue'), component: () => import('../views/zhongchou/index.vue'),
@ -72,7 +67,7 @@ const routes = [
] ]
// 创建路由实例 // 创建路由实例
const router = createRouter({ const router = createRouter({
history: createWebHistory(import.meta.env.VITE_PUBLIC_PATH),
history: createWebHistory('/testBack/'),
routes routes
}) })
// 导出 // 导出

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

@ -143,7 +143,7 @@ const editForm = ref({
gradeId: '', gradeId: '',
imageUrl: null imageUrl: null
}) })
const uploadUrl = 'http://39.101.133.168:8828/hljw/api/aws/upload';
const uploadUrl = '/hljw/api/aws/upload';
const formRef = ref(null) const formRef = ref(null)
const uploadRef = ref(null) const uploadRef = ref(null)

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

@ -1,18 +1,91 @@
<template> <template>
<h2>等级管理</h2> <h2>等级管理</h2>
<el-card style=" 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>
<el-card style=" 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: '60px' }">
<el-table-column type="index" label="ID" width="120px" fixed="left" >
<template #default="scope">
{{ pagination.pageSize * (pagination.pageNum - 1) + scope.$index + 1 }}
<!-- 等级表格 -->
<div class="table-container">
<el-table :data="tableData" style="width: 100%" :row-style="{ height: '60px' }">
<el-table-column type="index" label="ID" width="120px" fixed="left">
<template #default="scope">
{{ pagination.pageSize * (pagination.pageNum - 1) + scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column prop="gradeName" label="等级名称" width="240" 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="240" align="center" />
<el-table-column prop="operation" fixed="right" width="240" 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="deleteGrade(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> </template>
</el-table-column> </el-table-column>
<el-table-column prop="gradeName" label="等级名称" width="240" align="center" /> <el-table-column prop="gradeName" label="等级名称" width="240" align="center" />
@ -98,159 +171,159 @@ import { ElMessage, ElMessageBox } from 'element-plus'
import { getLevelList, addLevel, deleteGrade, updateGrade } from '@/api/manage/level' import { getLevelList, addLevel, deleteGrade, updateGrade } from '@/api/manage/level'
const tableData = ref([]) const tableData = ref([])
const pagination = ref({ const pagination = ref({
pageNum: 1,
pageSize: 10,
total:0
pageNum: 1,
pageSize: 10,
total: 0
}) })
const addVisible = ref(false) const addVisible = ref(false)
const editVisible = ref(false) const editVisible = ref(false)
const dialogTitle = ref('') const dialogTitle = ref('')
const addForm = ref({ const addForm = ref({
gradeName: '',
amount: '',
perWin: '',
sort: ''
gradeName: '',
amount: '',
perWin: '',
sort: ''
}) })
const editForm = ref({}) const editForm = ref({})
// //
const showAddDialog = () => { const showAddDialog = () => {
dialogTitle.value = '添加等级'
addVisible.value = true
dialogTitle.value = '添加等级'
addVisible.value = true
} }
// //
const editLevel = (row) => { 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
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 () => { const getLevels = async () => {
try {
const res = await getLevelList({
pageNum: pagination.value.pageNum,
pageSize: pagination.value.pageSize
})
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('请求失败,请重试')
}
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 () => { 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('添加失败,请重试')
}
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 () => { 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('修改失败,请重试')
}
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 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 = () => { const resetForm = () => {
addForm.value = {
gradeName: '',
amount: '',
perWin: '',
sort: ''
}
addForm.value = {
gradeName: '',
amount: '',
perWin: '',
sort: ''
}
} }
const handleSizeChange = (val) => { const handleSizeChange = (val) => {
pagination.value.pageSize = val
pagination.value.pageNum = 1
getLevels()
pagination.value.pageSize = val
pagination.value.pageNum = 1
getLevels()
} }
const handleCurrentChange = (val) => { const handleCurrentChange = (val) => {
pagination.value.pageNum = val
getLevels()
pagination.value.pageNum = val
getLevels()
} }
onMounted(() => { onMounted(() => {
getLevels()
getLevels()
}) })
</script> </script>
@ -263,12 +336,12 @@ min-height: 80vh;
} }
.pagination { .pagination {
padding: 10px 20px;
background-color: #fff;
border-top: 1px solid #ebeef5;
display: flex;
justify-content: flex-start;
/* 改为左对齐 */
padding: 10px 20px;
background-color: #fff;
border-top: 1px solid #ebeef5;
display: flex;
justify-content: flex-start;
/* 改为左对齐 */
} }
.action-buttons { .action-buttons {
@ -276,7 +349,7 @@ margin-bottom: 20px;
} }
.table-container { .table-container {
max-height: 650px;
overflow-y: auto;
max-height: 650px;
overflow-y: auto;
} }
</style> </style>

37
activitylink/vite.config.js

@ -1,24 +1,31 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
export default defineConfig({ export default defineConfig({
// 设置打包后静态资源的基础路径为 testBack
base: '/testBack/',
plugins: [vue()], plugins: [vue()],
resolve: { resolve: {
alias: { alias: {
'@': path.resolve(__dirname, './src') '@': path.resolve(__dirname, './src')
} }
}, },
server: {
proxy: {
'/api': {
target: 'https://dbqb.nfdxy.net/devLotApi', // 后端基础地址
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''), // 移除 /api 前缀
// 或者更精确的重写(根据后端路径调整):
// rewrite: (path) => path.replace(/^\/api\/admin/, '/admin'),
},
},
server: {
proxy: {
'/api': {
target: 'https://dbqb.nfdxy.net', // 后端基础地址
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''), // 移除 /api 前缀
// 或者更精确的重写(根据后端路径调整):
// rewrite: (path) => path.replace(/^\/api\/admin/, '/admin'),
},
'/hljw/api/aws/upload': {
target: 'http://39.101.133.168:8828', // 上传接口的基础地址
changeOrigin: true, // 开启跨域
rewrite: (path) => path.replace(/^\/hljw/, '/hljw'), // 保留原路径
}
}, },
})
},
},
);

13
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>Vite + Vue</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

2262
package-lock.json
File diff suppressed because it is too large
View File

20
package.json

@ -0,0 +1,20 @@
{
"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",
"pinia": "^3.0.3",
"vite": "^4.5.3",
"vue": "^3.5.17",
"vue-router": "^4.5.1"
}
}

1
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
src/App.vue

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

4
src/api/API.js

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

1
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>

BIN
src/img/image.png

After

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

17
src/main.js

@ -0,0 +1,17 @@
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'
// createApp(App).use(router).mount('#app')
const app = createApp(App)
const pinia = createPinia()
app.use(router)
app.use(pinia)
app.use(ElementPlus, {
locale: zhCn,
})
app.mount('#app')

74
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: '/choujiang',
name: 'choujiang',
component: () => import('../views/choujiang/index.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'),
}
]
}
]
// 创建路由实例
const router = createRouter({
history: createWebHistory(import.meta.env.VITE_PUBLIC_PATH),
routes
})
// 导出
export default router

21
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
})

26
src/stone/giftFixedListStone.js

@ -0,0 +1,26 @@
// 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;
};
const getList = async () => {
// 示例请求逻辑
// const res = await axios.get('xxx')
return '123';
};
// 暴露出去
return {
fixedGiftName,
setFixedGiftName,
getList
};
});

79
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;
}
}

130
src/utils/request.js

@ -0,0 +1,130 @@
import axios from 'axios'
import { ElMessage } from 'element-plus'
import { config } from '@/config'
const ERROR_MESSAGES = {
badRequest: '请求错误(400)',
unauthorized: '未授权,请登录(401)',
forbidden: '拒绝访问(403)',
notFound: `请求地址出错: ${'[具体 URL 将在这里被替换]'}`,
methodNotAllowed: '请求方法未允许(405)',
requestTimeout: '请求超时(408)',
internalServerError: '服务器内部错误(500)',
notImplemented: '服务未实现(501)',
badGateway: '网络错误(502)',
serviceUnavailable: '服务不可用(503)',
gatewayTimeout: '网络超时(504)',
httpVersionNotSupported: 'HTTP 版本不受支持(505)',
defaultConnectionError: '连接错误: [原始错误消息]',
networkError: '网络异常,请检查后重试!',
serverFailure: '连接到服务器失败,请联系管理员'
}
const service = axios.create({
baseURL: '', // url = base url + request url+
// timeout: 50000,
withCredentials: false // send cookies when cross-domain requests
// headers: {
// // clear cors
// 'Cache-Control': 'no-cache',
// Pragma: 'no-cache'
// }
})
const setErrorMsg = (error) => {
if (error && error.response) {
switch (error.response.status) {
case 400:
error.message = ERROR_MESSAGES.badRequest
break
case 401:
error.message = ERROR_MESSAGES.unauthorized
break
case 403:
error.message = ERROR_MESSAGES.forbidden
break
case 404:
error.message = ERROR_MESSAGES.notFound.replace(
'[具体 URL 将在这里被替换]',
error.response.config.url
)
break
case 405:
error.message = ERROR_MESSAGES.methodNotAllowed
break
case 408:
error.message = ERROR_MESSAGES.requestTimeout
break
case 500:
error.message = ERROR_MESSAGES.internalServerError
break
case 501:
error.message = ERROR_MESSAGES.notImplemented
break
case 502:
error.message = ERROR_MESSAGES.badGateway
break
case 503:
error.message = ERROR_MESSAGES.serviceUnavailable
break
case 504:
error.message = ERROR_MESSAGES.gatewayTimeout
break
case 505:
error.message = ERROR_MESSAGES.httpVersionNotSupported
break
default:
error.message = ERROR_MESSAGES.defaultConnectionError.replace(
'[原始错误消息]',
error.message
)
}
} else {
if (error.message === 'Network Error') {
error.message = ERROR_MESSAGES.networkError
} else {
error.message = ERROR_MESSAGES.serverFailure
}
}
return error.message
}
// Request interceptors
service.interceptors.request.use(
(config) => {
// 在此处添加请求头等,如添加 token
// if (store.state.token) {
// config.headers['Authorization'] = `Bearer ${store.state.token}`
// }
return config
},
(error) => {
return Promise.reject(error)
}
)
// Response interceptors
service.interceptors.response.use(
async (response) => {
// await new Promise(resovle => setTimeout(resovle, 3000));
// if (response.config.loadingInstance) {
// response.config.loadingInstance.close();
// }
const res = response.data
if (res.code !== 200) {
const errorMsg = res.msg || 'Unkonw error'
// ElMessage.error(errorMsg)
// return Promise.reject(new Error(res.msg || 'Error'))
return response.data
} else {
return response.data
}
},
(error) => {
const errorMessage = setErrorMsg(error)
ElMessage.error(errorMessage)
return Promise.reject(error)
}
)
export default service

0
activitylink/src/views/choujiang/index.vue → src/views/choujiang/index.vue

17
src/views/homePage.vue

@ -0,0 +1,17 @@
<template>
<div>
<button @click="router.push('/choujiang')">抽奖</button>
<button @click="router.push('/zhongchou')">众筹</button>
</div>
</template>
<script setup>
import { useRouter } from "vue-router";
const router = useRouter();
</script>
<style scoped>
</style>

282
src/views/zhongchou/activity/detail/index.vue

@ -0,0 +1,282 @@
<!-- 美股是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="searchName" placeholder="请输入姓名"></el-input>
</el-form-item>
<el-form-item label="精网号">
<el-input v-model="searchJingwangId" placeholder="请输入精网号" @input="handleJingwangIdInput"></el-input>
</el-form-item>
<el-form-item label="市场" class="market-item">
<el-select v-model="searchMarket" 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 searchName = ref('')
const searchJingwangId = ref('')
const searchMarket = ref('')
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:', searchName.value, searchJingwangId.value, searchMarket.value)
}
//
const handleReset = () => {
searchName.value = ''
searchJingwangId.value = ''
searchMarket.value = ''
}
//
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) => {
searchJingwangId.value = 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>

242
src/views/zhongchou/activity/index.vue

@ -0,0 +1,242 @@
<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="centerDialogVisible = true">添加活动</el-button>
</div>
<!-- 其他内容区域 -->
<div class="content-area">
<el-table :data="currentPageData" style="width: auto" :row-style="{ height: '60px' }">
<el-table-column prop="name" label="活动名称"></el-table-column>
<el-table-column prop="stock1" label="股票一"></el-table-column>
<el-table-column prop="stock2" label="股票二"></el-table-column>
<el-table-column label="数据统计">
<template #default="{ $index }">
<a href="#" style="color: red;" @click.prevent="goToDetail">查看详情</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"
/>
</template>
</el-table-column>
</el-table>
<el-dialog
v-model="centerDialogVisible"
title="添加活动"
width="500"
align-center
>
<el-form ref="addForm" :model="activity" label-width="80px">
<el-form-item label="活动名称" prop="name">
<el-input v-model="activity.name" placeholder="请输入活动名称" />
</el-form-item>
<el-form-item label="股票一" prop="stock1">
<el-input v-model="activity.stock1" placeholder="请输入股票一" />
</el-form-item>
<el-form-item label="股票二" prop="stock2">
<el-input v-model="activity.stock2" placeholder="请输入股票二" />
</el-form-item>
<el-form-item label="活动状态" prop="status">
<el-select v-model="activity.status" placeholder="请选择活动状态">
<el-option label="进行中" value="1" v-model="activity.status"></el-option>
<el-option label="已结束" value="0" v-model="activity.status"></el-option>
</el-select>
</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 } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const centerDialogVisible = ref(false)
//
const tableData = ref([
{ name: '周年庆众筹', stock1: '美股', stock2: '港股', status: '0' },
{ name: '中秋众筹', stock1: 'A股', stock2: '美股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
{ name: '国庆众筹', stock1: '港股', stock2: '日股', status: '0' },
// ... ...
]);
//
const cancel = () => {
centerDialogVisible.value = false
activity.value ={
name: '',
stock1: '',
stock2: '',
status: ''
}
}
//
const addActivity = () => {
centerDialogVisible.value = false
//TODO:
activity.value ={
name: '',
stock1: '',
stock2: '',
status: ''
}
}
const activity =ref({
name: '',
stock1: '',
stock2: '',
status: ''
})
//
const currentPage = ref(1);
const pageSize = ref(10); // 5
//
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 = () => {
router.push({ name: 'activityDetail' });
};
const goToSet = () => {
router.push({ name: 'activitySet' });
};
</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
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%" :rule="rules">
<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('');
const usStockBoostCount = ref(234);
const usStockAddCount = ref('');
const usStockDisplayCount = ref(345);
const hkStockBoostCount = ref(164);
const hkStockAddCount = ref('');
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 = '';
showInitialConfirmDialog.value = false;
};
//
const confirmAdd = () => {
const type = pendingAction.value;
if (type === 'us') {
usStockBoostCount.value += parseInt(usStockAddCount.value);
usStockDisplayCount.value = usStockBoostCount.value;
usStockAddCount.value = '';
} else if (type === 'hk') {
hkStockBoostCount.value += parseInt(hkStockAddCount.value);
hkStockDisplayCount.value = hkStockBoostCount.value;
hkStockAddCount.value = '';
}
//
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>

272
src/views/zhongchou/gift/importFixedList/index.vue

@ -0,0 +1,272 @@
<template>
<el-card style="margin-top: 50px; min-height: 90vh; max-height: 90vh;">
<!-- 头部标题区域 -->
<template #header>
<div style="display: flex; align-items: center; justify-content: space-between;">
<span style="font-size: 18px; font-weight: bold;">导入内定名单--{{ giftStore.fixedGiftName }}</span>
<el-button type="primary" @click="goBack">
<i class="el-icon-back"></i> 返回
</el-button>
</div>
</template>
<!-- 搜索和操作区域 -->
<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="searchName"
placeholder="请输入姓名"
style="width: 150px;"
clearable
></el-input>
<span style="white-space: nowrap; margin-left: 10px;">精网号</span>
<el-input
v-model="searchJingwangId"
placeholder="请输入精网号"
style="width: 180px;"
clearable
@input="handleJingwangIdInput"
></el-input>
<el-button type="primary" @click="search" 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="filteredUsers" 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="jingwangId" 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="centerDialogVisible"
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="jingwangId">
<el-input v-model="winuser.jingwangId" placeholder="请输入中奖用户精网号" @input="handleJingwangIdInput"/>
</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 } from 'vue'
import { useRouter } from 'vue-router'
import { usegiftFixedListStone } from '@/stone/giftFixedListStone';
const giftStore = usegiftFixedListStone();
const router = useRouter()
const centerDialogVisible = ref(false)
//
const users = ref([
{
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
},
])
//
const searchText = ref('')
const searchJingwangId = ref('')
//
const currentPage = ref(1)
const pageSize = ref(10)
const jumpPage = ref('')
const total = computed(() => users.value.length)
//
const filteredUsers = computed(() => {
//
const start = (currentPage.value - 1) * pageSize.value
const end = start + pageSize.value
return users.value.slice(start, end)
})
const winuser=ref({
name: '',
jingwangId: '',
})
//
const deleteUser = (user) => {
const index = users.value.findIndex(u => u.id === user.id)
if (index !== -1) {
users.value.splice(index, 1)
}
}
//
const batchDelete = () => {
//
console.log('执行批量删除')
}
//
const addUser = () => {
//
centerDialogVisible.value = true
}
//
const cancel = () => {
centerDialogVisible.value = false
winuser.value ={
name: '',
jingwangId: ''
}
}
//
const addwinUser = () => {
centerDialogVisible.value = false
//TODO:
winuser.value ={
name: '',
jingwangId: ''
}
}
// Excel
const importExcel = () => {
//
console.log('导入Excel')
}
//
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 handleJingwangIdInput = (value) => {
searchJingwangId.value = value.replace(/\D/g, '')
}
//
const goBack = () => {
router.back()
}
</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>

266
src/views/zhongchou/gift/importuser/index.vue

@ -0,0 +1,266 @@
<template>
<el-card style="margin-top: 50px; min-height: 90vh; max-height: 90vh;">
<!-- 头部标题区域 -->
<template #header>
<div style="display: flex; align-items: center; justify-content: space-between;">
<span style="font-size: 18px; font-weight: bold;">导入抽奖用户</span>
<el-button type="primary" @click="goBack">
<i class="el-icon-back"></i> 返回
</el-button>
</div>
</template>
<!-- 搜索和操作区域 -->
<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="searchName"
placeholder="请输入姓名"
style="width: 150px;"
clearable
></el-input>
<span style="white-space: nowrap; margin-left: 10px;">精网号</span>
<el-input
v-model="searchJingwangId"
placeholder="请输入精网号"
style="width: 180px;"
clearable
@input="handleJingwangIdInput"
></el-input>
<el-button type="primary" @click="search" 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="filteredUsers" 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="jingwangId" 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="centerDialogVisible"
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="jingwangId">
<el-input v-model="winuser.jingwangId" placeholder="请输入中奖用户精网号" @input="handleJingwangIdInput"/>
</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 } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const centerDialogVisible = ref(false)
//
const users = ref([
{
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
}, {
id: 1,
name: '张家伟',
jingwangId: '90047666'
},
])
//
const searchText = ref('')
const searchJingwangId = ref('')
//
const currentPage = ref(1)
const pageSize = ref(10)
const jumpPage = ref('')
const total = computed(() => users.value.length)
//
const filteredUsers = computed(() => {
//
const start = (currentPage.value - 1) * pageSize.value
const end = start + pageSize.value
return users.value.slice(start, end)
})
const winuser=ref({
name: '',
jingwangId: '',
})
//
const deleteUser = (user) => {
const index = users.value.findIndex(u => u.id === user.id)
if (index !== -1) {
users.value.splice(index, 1)
}
}
//
const batchDelete = () => {
//
console.log('执行批量删除')
}
//
const addUser = () => {
//
centerDialogVisible.value = true
}
//
const cancel = () => {
centerDialogVisible.value = false
winuser.value ={
name: '',
jingwangId: ''
}
}
//
const addwinUser = () => {
centerDialogVisible.value = false
//TODO:
winuser.value ={
name: '',
jingwangId: ''
}
}
// Excel
const importExcel = () => {
//
console.log('导入Excel')
}
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 handleJingwangIdInput = (value) => {
searchJingwangId.value = value.replace(/\D/g, '')
}
</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>

246
src/views/zhongchou/gift/index.vue

@ -0,0 +1,246 @@
<!-- 由于本地图片在js中不会自动解析@所以需要用方法getImageUrl()获取图片路径但是如果图片用的绝对路径则不需要 -->
<template>
<el-card style="margin-top: 50px; min-height: 90vh; max-height: 90vh; display: flex; flex-direction: column;">
<div class="gift-management-container" style="flex: 1; overflow-y: auto;">
<h2>礼品管理</h2>
<!-- 添加礼品和导入用户按钮 -->
<div class="action-buttons">
<el-button type="primary" @click="showAddDialog">添加礼品</el-button>
<el-button @click="goToimportUsers">导入抽奖用户</el-button>
</div>
<div class="table-container" style="flex: 1; overflow-y: auto;">
<el-table :data="gifts" style="width: 100%" class="gift-table">
<el-table-column prop="id" 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.image"
:src="getImageUrl(scope.row.image)"
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="name" label="名称" width="300" align="center"></el-table-column>
<el-table-column prop="level" label="等级" width="200" align="center"></el-table-column>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button size="big" @click="goToimportFixedList(scope.row)">导入内定名单</el-button>
<el-button size="big" @click="editGift(scope.row)">编辑</el-button>
<el-button size="big" type="danger" @click="deleteGift(scope.row)">删除</el-button>
</template>
</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="gifts.length"
></el-pagination>
<!-- 添加/编辑礼品对话框 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="40%">
<el-form :model="form" label-width="100px">
<el-form-item label="礼品名称">
<el-input v-model="form.name" placeholder="请输入礼品名称"></el-input>
</el-form-item>
<el-form-item label="礼品等级">
<el-select v-model="form.level" placeholder="请选择礼品等级">
<el-option label="特等奖" value="特等奖"></el-option>
<el-option label="一等奖" value="一等奖"></el-option>
<el-option label="二等奖" value="二等奖"></el-option>
<el-option label="三等奖" value="三等奖"></el-option>
<el-option label="四等奖" value="四等奖"></el-option>
<el-option label="五等奖" value="五等奖"></el-option>
</el-select>
</el-form-item>
<el-form-item label="礼品图片">
<el-upload
action="#"
list-type="picture-card"
:auto-upload="false"
:on-change="handleImageChange"
>
<el-icon><Plus /></el-icon>
</el-upload>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm">确认</el-button>
</span>
</template>
</el-dialog>
</el-card>
</template>
<script setup>
import { ref, computed } 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';
const router = useRouter();
// URL
const getImageUrl = (path) => {
// @
if (path.startsWith('@')) {
return path.replace('@', '/src')
}
return path
}
const giftStore = usegiftFixedListStone();
// -
const gifts = ref([
{ id: 1, image: '@/img/image.png', name: 'zimomo', level: '特等奖' },
{ id: 2, image: '@/img/image.png', name: '高级耳机', level: '一等奖' },
{ id: 3, image: '@/img/image.png', name: '智能手表', level: '二等奖' },
{ id: 4, image: '@/img/image.png', name: '蓝牙音箱', level: '三等奖' },
{ id: 5, image: '@/img/image.png', name: '充电宝', level: '四等奖' },
{ id: 6, image: '@/img/image.png', name: 'U盘', level: '五等奖' },
{ id: 6, image: '@/img/image.png', name: 'U盘', level: '五等奖' },
{ id: 6, image: '@/img/image.png', name: 'U盘', level: '五等奖' },
{ id: 6, image: '@/img/image.png', name: 'U盘', level: '五等奖' },
{ id: 6, image: '@/img/image.png', name: 'U盘', level: '五等奖' },
{ id: 6, image: '@/img/image.png', name: 'U盘', level: '五等奖' },
{ id: 6, image: '@/img/image.png', name: 'U盘', level: '五等奖' },
{ id: 6, image: '@/img/image.png', name: 'U盘', level: '五等奖' },
])
//
const currentPage = ref(1)
const pageSize = ref(10)
//
const handleSizeChange = (val) => {
pageSize.value = val
}
const handleCurrentChange = (val) => {
currentPage.value = val
}
//
const dialogVisible = ref(false)
const dialogTitle = ref('添加礼品')
const form = ref({
id: null,
name: '',
level: '',
image: null
})
const showAddDialog = () => {
dialogTitle.value = '添加礼品'
form.value = { id: null, name: '', level: '', image: null }
dialogVisible.value = true
}
const editGift = (row) => {
dialogTitle.value = '编辑礼品'
form.value = { ...row }
dialogVisible.value = true
}
const submitForm = () => {
if (!form.value.name || !form.value.level) {
ElMessage.error('请填写完整信息')
return
}
if (form.value.id) {
//
const index = gifts.value.findIndex(item => item.id === form.value.id)
if (index !== -1) {
gifts.value[index] = { ...form.value }
}
} else {
//
const newId = gifts.value.length > 0 ? Math.max(...gifts.value.map(item => item.id)) + 1 : 1
gifts.value.push({
id: newId,
...form.value
})
}
dialogVisible.value = false
ElMessage.success('操作成功')
}
const deleteGift = (row) => {
ElMessageBox.confirm('确定要删除该礼品吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
gifts.value = gifts.value.filter(item => item.id !== row.id)
ElMessage.success('删除成功')
}).catch(() => {
//
})
}
const goToimportFixedList = (row) => {
giftStore.setFixedGiftName(row.name);
router.push({ name: 'importFixedList' });
}
const goToimportUsers = () => {
router.push({ name: 'importUsers' });
}
const handleImageChange = (file) => {
form.value.image = file.raw
}
</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;
}
</style>

128
src/views/zhongchou/index.vue

@ -0,0 +1,128 @@
<!-- <template>
<div>
<el-button type="primary">众筹</el-button>
</div>
</template>
<script setup>
</script>
<style scoped>
</style> -->
<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)
}
const goToLevel = () => {
router.push({ name: 'zhongchoulevel' })
}
const goToGift = () => {
router.push({ name: 'zhongchougift' })
}
const goToWinning = () => {
router.push({ name: 'zhongchouwinning' })
}
const goToActivity = () => {
router.push({ name: 'zhongchouactivity' })
}
</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">
<el-icon><Promotion /></el-icon>
<span>后台管理系统</span>
</el-menu-item>
<el-menu-item @click="goToLevel">
<el-icon><location /></el-icon>
<span>等级管理</span>
</el-menu-item>
<el-menu-item @click="goToGift">
<el-icon><icon-menu /></el-icon>
<span>礼品管理</span>
</el-menu-item>
<el-menu-item @click="goToWinning">
<el-icon><document /></el-icon>
<span>中奖管理</span>
</el-menu-item>
<el-menu-item @click="goToActivity">
<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>

274
src/views/zhongchou/level/index.vue

@ -0,0 +1,274 @@
<template>
<el-card style="margin-top:50px ; min-height: 90vh; max-height: 90vh;">
<div class="gray-container">
<h2>等级管理</h2>
<el-button type="primary" @click="showAdd = true">添加等级</el-button>
<div class="table-container" style="flex: 1; overflow-y: auto;">
<el-table :data="tableData" style="width: 100%" :row-style="{ height: '55px' }">
<el-table-column type="index" label="ID" width="150" align="center"/>
<el-table-column prop="gradeName" label="等级名称" width="200" align="center"/>
<el-table-column prop="num" label="数量" width="250" align="center"/>
<el-table-column prop="numPeople" label="每轮抽取人数" width="300" align="center"/>
<el-table-column prop="sort" label="排序" width="200" align="center"/>
<el-table-column fixed="right" prop="operation" label="操作" align="center">
<template #default="scope">
<div style="display: flex; gap: 10px;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<el-button type="primary" text @click="editInit(scope.row)">编辑</el-button>
&nbsp;&nbsp;&nbsp;
<el-button type="primary" text @click="showSet = true">设置多个</el-button>
<el-popconfirm title="确定将此用户删除吗?">
<template #reference>
<el-button type="danger" text>删除</el-button>
</template>
<template #actions="{ confirm, cancel }">
<el-button size="small" @click="cancel">取消</el-button>
<el-button type="primary" size="small" @click="confirm">确定</el-button>
</template>
</el-popconfirm>
</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"></el-pagination>
</el-card>
<el-dialog v-model="showAdd" :rules="rules" style="width:600px" align-center>
<el-header>
<h2>添加等级</h2>
</el-header>
<el-form :model="addObj" :rules="rules" ref="addForm">
<div class="marginTop">
<span style="width: 100px; display: inline-block; text-align: right;">等级名称</span><el-input
v-model="addObj.gradeName" placeholder="请输入" style="width:200px"></el-input>
</div>
<div class="marginTop">
<span style="width: 100px; display: inline-block; text-align: right;">数量</span><el-input
v-model="addObj.num" placeholder="请输入" style="width:200px"></el-input>
</div>
<div class="marginTop">
<span style="width: 100px; display: inline-block; text-align: right;">每轮抽取人数</span><el-input
v-model="addObj.numPeople" placeholder="请输入" style="width:200px"></el-input>
</div>
<div class="marginTop">
<span style="width: 100px; display: inline-block; text-align: right;">排序</span><el-input
v-model="addObj.sort" placeholder="请输入" style="width:200px"></el-input>
</div>
</el-form>
<template #footer>
<div class="dialog-footer" style="text-align: right; margin-top:10px">
<el-button @click="showAdd = false">取消</el-button>
<el-button type="primary" @click="showAdd = false"><!-- 改一下 -->
确定
</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="showEdit" :rules="rules" style="width:600px" align-center>
<el-header>
<h2>编辑等级</h2>
</el-header>
<el-form :model="editObj" :rules="rules" ref="addForm">
<div class="marginTop">
<span style="width: 100px; display: inline-block; text-align: right;">等级名称</span><el-input
v-model="editObj.gradeName" placeholder="请输入" style="width:200px"></el-input>
</div>
<div class="marginTop">
<span style="width: 100px; display: inline-block; text-align: right;">数量</span><el-input
v-model="editObj.num" placeholder="请输入" style="width:200px"></el-input>
</div>
<div class="marginTop">
<span style="width: 100px; display: inline-block; text-align: right;">每轮抽取人数</span><el-input
v-model="editObj.numPeople" placeholder="请输入" style="width:200px"></el-input>
</div>
<div class="marginTop">
<span style="width: 100px; display: inline-block; text-align: right;">排序</span><el-input
v-model="editObj.sort" placeholder="请输入" style="width:200px"></el-input>
</div>
</el-form>
<template #footer>
<div class="dialog-footer" style="text-align: right; margin-top:10px">
<el-button @click="showEdit = false">取消</el-button>
<el-button type="primary" @click="showEdit = false"><!-- 改一下 -->
确定
</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="showSet" :rules="rules" style="width:600px" align-center>
<el-header>
<h2>设置多个</h2>
</el-header>
<el-form :model="setObj" :rules="rules" ref="addForm">
<div class="marginTop">
<span style="width: 100px; display: inline-block; text-align: right;">等级名称</span><el-input
v-model="setObj.gradeName" placeholder="请输入" style="width:200px"></el-input>
</div>
<div class="marginTop">
<span style="width: 100px; display: inline-block; text-align: right;">数量</span><el-input
v-model="setObj.num" placeholder="请输入" style="width:200px"></el-input>
</div>
<div class="marginTop">
<span style="width: 100px; display: inline-block; text-align: right;">每轮抽取人数</span><el-input
v-model="setObj.numPeople" placeholder="请输入" style="width:200px"></el-input>
</div>
<div class="marginTop">
<span style="width: 100px; display: inline-block; text-align: right;">排序</span><el-input
v-model="setObj.sort" placeholder="请输入" style="width:200px"></el-input>
</div>
</el-form>
<template #footer>
<div class="dialog-footer" style="text-align: right; margin-top:10px">
<el-button @click="showSet = false">取消</el-button>
<el-button type="primary" @click="showSet = false"><!-- 改一下 -->
确定
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, reactive, watch, onMounted } from 'vue'
const showAdd = ref(false)
const showEdit = ref(false)
const showSet = ref(false)
const addObj = ref({
gradeName: '',
num: 0,
numPeople: 0,
sort: 0
})
const editObj = ref({})//
const setObj = ref({})
const pagination = ref({
pageNum: 1,
pageSize: 10,
total: 0
})
const editInit = function (row) {
editObj.value = row
showEdit.value = true
}
const tableData = ref([
{
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}, {
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}, {
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}, {
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}, {
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}, {
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}, {
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}, {
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}, {
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}, {
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}, {
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}, {
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}, {
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}, {
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}, {
id: 1,
num: 1,
gradeName: '这是假数据',
numPeople: 10,
sort: 1
}
])
</script>
<style scoped>
.marginTop {
margin-top: 10px;
}
.gray-container {
width: 100%; /* 宽度自适应 */
background-color: #ffffff; /* 浅灰色背景 */
padding: 20px; /* 内边距 */
box-sizing: border-box; /* 包含内边距在总宽度内 */
min-height: 80vh; /* 设置最小高度 */
overflow-x: hidden;
}
.table-container {
max-height: 600px; /* 或者根据你的页面布局调整 */
overflow-y: auto;
}
</style>

251
src/views/zhongchou/winning/index.vue

@ -0,0 +1,251 @@
<!-- 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="searchName" placeholder="请输入姓名"></el-input>
</el-form-item>
<el-form-item label="精网号">
<el-input
v-model="searchJingwangId"
placeholder="请输入精网号"
@input="handleJingwangIdInput"
></el-input>
</el-form-item>
<el-form-item label="中奖等级">
<el-select v-model="searchPrizeLevel" 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 searchName = ref('')
const searchJingwangId = ref('')
const searchPrizeLevel = ref('')
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
})
// 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) => {
searchJingwangId.value = value.replace(/\D/g, '')
}
//
const handleReset = () => {
searchJingwangId.value = ''
searchName.value = ''
searchPrizeLevel.value = ''
}
</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>

14
vite.config.js

@ -0,0 +1,14 @@
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path' // 需要引入 path 模块
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src') // 将 @ 映射为 src 目录
},
extensions: ['.js', '.vue', '.json', '.mjs'] // 确保支持 .js 文件
}
})
Loading…
Cancel
Save