first commit

master
cody 3 weeks ago
parent 458df6542b
commit 1ffbd97577

@ -0,0 +1,81 @@
import request from '@/utils/request'
export function getOverview(params) {
return request({
method: 'get',
url: '/api/admin/schedule-overview/overview',
params
})
}
export function getSystemList(params) {
return request({
method: 'get',
url: '/api/admin/schedule-overview/systems/index',
params
})
}
export function saveSystem(data) {
return request({
method: 'post',
url: '/api/admin/schedule-overview/systems/save',
data
})
}
export function destroySystem(params) {
return request({
method: 'get',
url: '/api/admin/schedule-overview/systems/destroy',
params
})
}
export function getCourseList(params) {
return request({
method: 'get',
url: '/api/admin/schedule-overview/courses/index',
params
})
}
export function saveCourse(data) {
return request({
method: 'post',
url: '/api/admin/schedule-overview/courses/save',
data
})
}
export function destroyCourse(params) {
return request({
method: 'get',
url: '/api/admin/schedule-overview/courses/destroy',
params
})
}
export function getScheduleList(params) {
return request({
method: 'get',
url: '/api/admin/schedule-overview/schedules/index',
params
})
}
export function saveSchedule(data) {
return request({
method: 'post',
url: '/api/admin/schedule-overview/schedules/save',
data
})
}
export function destroySchedule(params) {
return request({
method: 'get',
url: '/api/admin/schedule-overview/schedules/destroy',
params
})
}

@ -31,55 +31,68 @@ import Layout from '@/layout'
* a base page that does not have permission requirements
* all roles can be accessed
*/
export const constantRoutes = [{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/test',
component: () => import('@/views/component/test.vue'),
hidden: true
},
{
path: '/info',
component: Layout,
children: [{
path: 'password',
component: () => import('@/views/system/password'),
name: '密码修改',
meta: {
title: '密码修改'
}
}],
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: '课程发布管理',
component: () => import('@/views/course/index'),
meta: {
title: '课程发布管理',
icon: 'dashboard'
}
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/test',
component: () => import('@/views/component/test.vue'),
hidden: true
},
{
path: '/info',
component: Layout,
children: [{
path: 'password',
component: () => import('@/views/system/password'),
name: '密码修改',
meta: {
title: '密码修改'
}
}],
hidden: true
},
{
path: '/course/txl',
component: Layout,
redirect: '/dashboard',
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: '课程发布管理',
component: () => import('@/views/course/index'),
meta: {
title: '课程发布管理',
icon: 'dashboard'
}
}],
hidden: true
},
{
path: '/schedule-overview',
component: Layout,
redirect: '/schedule-overview/index',
children: [{
path: 'index',
name: '课程排期总览',
component: () => import('@/views/scheduleOverview/index'),
meta: {
title: '课程排期总览',
icon: 'table'
}
}]
},
{
path: '/course/txl',
component: Layout,
redirect: '/dashboard',
children: [{
path: '/course/txl',
name: '通讯录',
@ -140,18 +153,13 @@ export const constantRoutes = [{
}],
hidden: true
}
]
/**
* asyncRoutes
* the routes that need to be dynamically loaded based on user roles
*/
export const asyncRoutes = [
// 404 page must be placed at the end !!!
]
/**
* asyncRoutes
* the routes that need to be dynamically loaded based on user roles
*/
export const asyncRoutes = [
// 404 page must be placed at the end !!!
{
path: '*',
redirect: '/404',

@ -0,0 +1 @@
课程排期总览静态页面用于根据设计参考图快速复原前台展示结构,当前版本仅包含静态示意数据与布局样式。

File diff suppressed because it is too large Load Diff

@ -0,0 +1,235 @@
const STORAGE_KEY = 'schedule-overview-mock-store'
const getCurrentYear = () => String(new Date().getFullYear())
const clone = (data) => JSON.parse(JSON.stringify(data))
const createInitialState = () => {
const year = getCurrentYear()
return {
systems: [
{ id: 1, name: '0-1', sort: 1 },
{ id: 2, name: '0-10', sort: 2 },
{ id: 3, name: '10-100', sort: 3 },
{ id: 4, name: '产业链协同组织', sort: 4 },
{ id: 5, name: '科创人才服务', sort: 5 },
{ id: 6, name: '锚定资金舍客万人成员', sort: 6 }
],
courses: [
{ id: 1, system_id: 1, name: '领跑营', sort: 1 },
{ id: 2, system_id: 2, name: '高研班', sort: 1 },
{ id: 3, system_id: 3, name: '专题班', sort: 1 },
{ id: 4, system_id: 4, name: '产业加速营', sort: 1 },
{ id: 5, system_id: 4, name: '第二课堂', sort: 2 },
{ id: 6, system_id: 5, name: '人才研修', sort: 1 },
{ id: 7, system_id: 5, name: '科技大讲堂', sort: 2 },
{ id: 8, system_id: 6, name: '万人培训项目', sort: 1 }
],
schedules: [
{ id: 1, year, system_id: 1, course_id: 1, month: 5, title: '第二期领跑营', owner: '张三', location: '苏州', count_text: '招募 42人' },
{ id: 2, year, system_id: 1, course_id: 1, month: 7, title: '第三期领跑营', owner: '张三', location: '苏州', count_text: '招募 38人' },
{ id: 3, year, system_id: 1, course_id: 1, month: 9, title: '第四期领跑营', owner: '张三', location: '苏州', count_text: '招募 41人' },
{ id: 4, year, system_id: 1, course_id: 1, month: 10, title: '第五期领跑营', owner: '李四', location: '苏州', count_text: '招募 35人' },
{ id: 5, year, system_id: 2, course_id: 2, month: 3, title: '第七期高研班', owner: '李四', location: '苏州', count_text: '招募 31人' },
{ id: 6, year, system_id: 2, course_id: 2, month: 5, title: '第八期高研班', owner: '李四', location: '上海', count_text: '招募 44人' },
{ id: 7, year, system_id: 2, course_id: 2, month: 7, title: '第九期高研班', owner: '王五', location: '苏州', count_text: '招募 40人' },
{ id: 8, year, system_id: 2, course_id: 2, month: 8, title: '第十期高研班', owner: '王五', location: '深圳', count_text: '招募 36人' },
{ id: 9, year, system_id: 3, course_id: 3, month: 6, title: '研学营', owner: '王五', location: '苏州', count_text: '招募 45人' },
{ id: 10, year, system_id: 4, course_id: 4, month: 4, title: 'AI产业营', owner: '赵六', location: '苏州', count_text: '招募 36人' },
{ id: 11, year, system_id: 4, course_id: 4, month: 5, title: 'OCP加速营', owner: '赵六', location: '常州', count_text: '招募 34人' },
{ id: 12, year, system_id: 4, course_id: 4, month: 6, title: '并购闭门营', owner: '赵六', location: '北京', count_text: '招募 27人' },
{ id: 13, year, system_id: 4, course_id: 4, month: 8, title: '数字化闭门营', owner: '孙七', location: '成都', count_text: '招募 30人' },
{ id: 14, year, system_id: 4, course_id: 4, month: 9, title: '智造闭门营', owner: '孙七', location: '苏州', count_text: '招募 30人' },
{ id: 15, year, system_id: 5, course_id: 6, month: 7, title: '领军营先导班', owner: '周八', location: '苏州', count_text: '招募 32人' },
{ id: 16, year, system_id: 5, course_id: 6, month: 9, title: '领军营专题班', owner: '周八', location: '苏州', count_text: '招募 36人' },
{ id: 17, year, system_id: 6, course_id: 8, month: 4, title: '第一期万人营', owner: '张三', location: '苏州', count_text: '招募 75人' },
{ id: 18, year, system_id: 6, course_id: 8, month: 5, title: '第二期万人营', owner: '张三', location: '扬州', count_text: '招募 102人' },
{ id: 19, year, system_id: 6, course_id: 8, month: 6, title: '第三期万人营', owner: '张三', location: '苏州', count_text: '招募 104人' },
{ id: 20, year, system_id: 6, course_id: 8, month: 7, title: '第四期万人营', owner: '张三', location: '苏州', count_text: '招募 78人' },
{ id: 21, year, system_id: 6, course_id: 8, month: 8, title: '第五期万人营', owner: '张三', location: '苏州', count_text: '招募 83人' },
{ id: 22, year, system_id: 6, course_id: 8, month: 9, title: '第六期万人营', owner: '张三', location: '苏州', count_text: '招募 81人' },
{ id: 23, year, system_id: 6, course_id: 8, month: 10, title: '第七期万人营', owner: '张三', location: '苏州', count_text: '招募 74人' },
{ id: 24, year, system_id: 6, course_id: 8, month: 11, title: '第八期万人营', owner: '张三', location: '苏州', count_text: '招募 66人' },
{ id: 25, year, system_id: 6, course_id: 8, month: 12, title: '第九期万人营', owner: '张三', location: '苏州', count_text: '招募 58人' }
]
}
}
const getStorage = () => {
if (typeof window === 'undefined' || !window.localStorage) {
return null
}
return window.localStorage
}
const loadState = () => {
const storage = getStorage()
if (!storage) {
return createInitialState()
}
const cache = storage.getItem(STORAGE_KEY)
if (!cache) {
const initialState = createInitialState()
storage.setItem(STORAGE_KEY, JSON.stringify(initialState))
return initialState
}
try {
return JSON.parse(cache)
} catch (error) {
const initialState = createInitialState()
storage.setItem(STORAGE_KEY, JSON.stringify(initialState))
return initialState
}
}
const store = loadState()
const persist = () => {
const storage = getStorage()
if (storage) {
storage.setItem(STORAGE_KEY, JSON.stringify(store))
}
}
const nextId = (list) => list.reduce((max, item) => Math.max(max, Number(item.id) || 0), 0) + 1
const sortByName = (list) => clone(list).sort((a, b) => {
const sortDiff = Number(a.sort || 0) - Number(b.sort || 0)
if (sortDiff !== 0) {
return sortDiff
}
return String(a.name || '').localeCompare(String(b.name || ''), 'zh-CN')
})
const sortSchedules = (list) => clone(list).sort((a, b) => {
const yearDiff = Number(a.year || 0) - Number(b.year || 0)
if (yearDiff !== 0) {
return yearDiff
}
const monthDiff = Number(a.month || 0) - Number(b.month || 0)
if (monthDiff !== 0) {
return monthDiff
}
return String(a.title || '').localeCompare(String(b.title || ''), 'zh-CN')
})
export function listOverviewData() {
return Promise.resolve({
systems: sortByName(store.systems),
courses: sortByName(store.courses),
schedules: sortSchedules(store.schedules)
})
}
export function saveSystem(data) {
if (data.id) {
const index = store.systems.findIndex((item) => String(item.id) === String(data.id))
if (index > -1) {
store.systems.splice(index, 1, {
...store.systems[index],
name: data.name,
sort: Number(data.sort || 0)
})
}
} else {
store.systems.push({
id: nextId(store.systems),
name: data.name,
sort: Number(data.sort || 0)
})
}
persist()
return listOverviewData()
}
export function destroySystem({ id }) {
const courseIds = store.courses.filter((item) => String(item.system_id) === String(id)).map((item) => item.id)
store.systems = store.systems.filter((item) => String(item.id) !== String(id))
store.courses = store.courses.filter((item) => String(item.system_id) !== String(id))
store.schedules = store.schedules.filter((item) => String(item.system_id) !== String(id) && !courseIds.includes(item.course_id))
persist()
return listOverviewData()
}
export function saveCourse(data) {
if (data.id) {
const index = store.courses.findIndex((item) => String(item.id) === String(data.id))
if (index > -1) {
const previousCourse = store.courses[index]
store.courses.splice(index, 1, {
...previousCourse,
system_id: Number(data.system_id),
name: data.name,
sort: Number(data.sort || 0)
})
if (String(previousCourse.system_id) !== String(data.system_id)) {
store.schedules = store.schedules.map((item) => {
if (String(item.course_id) === String(data.id)) {
return {
...item,
system_id: Number(data.system_id)
}
}
return item
})
}
}
} else {
store.courses.push({
id: nextId(store.courses),
system_id: Number(data.system_id),
name: data.name,
sort: Number(data.sort || 0)
})
}
persist()
return listOverviewData()
}
export function destroyCourse({ id }) {
store.courses = store.courses.filter((item) => String(item.id) !== String(id))
store.schedules = store.schedules.filter((item) => String(item.course_id) !== String(id))
persist()
return listOverviewData()
}
export function saveSchedule(data) {
const payload = {
year: String(data.year || getCurrentYear()),
system_id: Number(data.system_id),
course_id: Number(data.course_id),
month: Number(data.month),
title: data.title,
owner: data.owner,
location: data.location,
count_text: data.count_text || ''
}
if (data.id) {
const index = store.schedules.findIndex((item) => String(item.id) === String(data.id))
if (index > -1) {
store.schedules.splice(index, 1, {
...store.schedules[index],
...payload
})
}
} else {
store.schedules.push({
id: nextId(store.schedules),
...payload
})
}
persist()
return listOverviewData()
}
export function destroySchedule({ id }) {
store.schedules = store.schedules.filter((item) => String(item.id) !== String(id))
persist()
return listOverviewData()
}

@ -39,19 +39,24 @@
</el-table-column>
</el-table>
</div>
<el-dialog title="角色编辑" :visible.sync="dialogFormVisible" width="30%">
<el-dialog
title="角色编辑"
:visible.sync="dialogFormVisible"
width="480px"
top="15vh"
>
<el-form :model="form" ref="form" :rules="rules" label-position="right" :label-width="formLabelWidth">
<el-form-item label="角色名称" prop="name">
<el-input v-model="form.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="数据权限" prop="allow_level">
<el-radio-group v-model="form.allow_level">
<el-radio :label="0">所有</el-radio>
<el-radio :label="1">部门</el-radio>
<el-radio :label="2">私有</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="数据权限" prop="allow_level">
<el-radio-group v-model="form.allow_level">
<el-radio :label="0">所有</el-radio>
<el-radio :label="1">部门</el-radio>
<el-radio :label="2">私有</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="排序">
<el-input v-model="form.sortnumber" autocomplete="off"></el-input>
@ -117,7 +122,7 @@
form: {
name: "",
id: "",
sortnumber: "0",
sortnumber: "0",
allow_level:0
},
userdata: [],
@ -249,4 +254,4 @@
</script>
<style>
</style>
</style>

@ -48,7 +48,12 @@
</el-table-column>
</el-table>
</div>
<el-dialog title="用户编辑" :visible.sync="dialogFormVisible" width="30%">
<el-dialog
title="用户编辑"
:visible.sync="dialogFormVisible"
width="480px"
top="15vh"
>
<el-form :model="form" :rules="rules" ref="form" label-position="right" :label-width="formLabelWidth">
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" autocomplete="off"></el-input>

@ -27,10 +27,8 @@ module.exports = {
*
*/
publicPath: process.env.ENV === 'staging' ? '/admin' : '/admin',
// 测试
outputDir: '/Users/mac/Documents/朗业/2025/s-苏州科技商学院/wx.sstbc.com/public/admin',
// 正式
// outputDir: '/Users/mac/Documents/朗业/2024/s-苏州科技商学院/wx.sstbc.com/public/admin',
// 前台打包输出到当前机器的 /Users/apple/www/wx.sstbc.com/public/admin 目录下
outputDir: '/Users/apple/www/wx.sstbc.com/public/admin',
assetsDir: 'static',
css: {
loaderOptions: { // 向 CSS 相关的 loader 传递选项

Loading…
Cancel
Save