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
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -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()
|
||||||
|
}
|
||||||
Loading…
Reference in new issue