├── .browserslistrc
├── babel.config.js
├── public
├── logo.png
├── favicon.ico
├── logo-192.png
├── logo-48.png
├── logo-96.png
├── export
│ ├── caigoujiaocaihuizongbiao.png
│ ├── chubanshetongjishuliangbiao.png
│ ├── kaoshikaochazongtidingshulv.png
│ ├── zhengdingjiaocaihuizongbiao.png
│ ├── jiaoshilingqujiaocaihuizongbiao.png
│ ├── zhengdingjiaocaiyangshuhuizongbiao.png
│ └── xueshengbanjilingqujiaocaifankuibiao.png
├── manifest.json
└── index.html
├── postcss.config.js
├── src
├── assets
│ └── logo.png
├── store.js
├── main.js
├── components
│ ├── ContentTitle.vue
│ └── TeacherModifyBookModal.vue
├── user.js
├── api.js
├── router.js
├── App.vue
├── views
│ ├── aao
│ │ ├── PlanList.vue
│ │ ├── Discount.vue
│ │ ├── NewPlan.vue
│ │ ├── Export.vue
│ │ └── Review.vue
│ ├── teacher
│ │ ├── Buy.vue
│ │ └── Add.vue
│ └── om
│ │ └── Review.vue
└── axios.js
├── .editorconfig
├── .gitignore
├── package.json
├── README.md
└── mock.json
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itning/TMPP-FrontEnd/master/public/logo.png
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | autoprefixer: {}
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itning/TMPP-FrontEnd/master/public/favicon.ico
--------------------------------------------------------------------------------
/public/logo-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itning/TMPP-FrontEnd/master/public/logo-192.png
--------------------------------------------------------------------------------
/public/logo-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itning/TMPP-FrontEnd/master/public/logo-48.png
--------------------------------------------------------------------------------
/public/logo-96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itning/TMPP-FrontEnd/master/public/logo-96.png
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itning/TMPP-FrontEnd/master/src/assets/logo.png
--------------------------------------------------------------------------------
/public/export/caigoujiaocaihuizongbiao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itning/TMPP-FrontEnd/master/public/export/caigoujiaocaihuizongbiao.png
--------------------------------------------------------------------------------
/public/export/chubanshetongjishuliangbiao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itning/TMPP-FrontEnd/master/public/export/chubanshetongjishuliangbiao.png
--------------------------------------------------------------------------------
/public/export/kaoshikaochazongtidingshulv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itning/TMPP-FrontEnd/master/public/export/kaoshikaochazongtidingshulv.png
--------------------------------------------------------------------------------
/public/export/zhengdingjiaocaihuizongbiao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itning/TMPP-FrontEnd/master/public/export/zhengdingjiaocaihuizongbiao.png
--------------------------------------------------------------------------------
/public/export/jiaoshilingqujiaocaihuizongbiao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itning/TMPP-FrontEnd/master/public/export/jiaoshilingqujiaocaihuizongbiao.png
--------------------------------------------------------------------------------
/public/export/zhengdingjiaocaiyangshuhuizongbiao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itning/TMPP-FrontEnd/master/public/export/zhengdingjiaocaiyangshuhuizongbiao.png
--------------------------------------------------------------------------------
/public/export/xueshengbanjilingqujiaocaifankuibiao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itning/TMPP-FrontEnd/master/public/export/xueshengbanjilingqujiaocaifankuibiao.png
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*.vue]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/src/store.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | Vue.use(Vuex)
5 |
6 | export default new Vuex.Store({
7 | state: {
8 | //当前路径
9 | now_path: ''
10 | },
11 | getters: {},
12 | mutations: {},
13 | actions: {}
14 | })
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw?
22 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './store'
5 | import Antd from 'ant-design-vue'
6 | import User from '@/user'
7 |
8 | import 'ant-design-vue/dist/antd.css'
9 |
10 | Vue.config.productionTip = false
11 | Vue.use(Antd)
12 | Vue.use(User)
13 |
14 | new Vue({
15 | router,
16 | store,
17 | render: h => h(App)
18 | }).$mount('#app')
19 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "教材采购系统",
3 | "name": "哈信息教材采购系统",
4 | "icons": [
5 | {
6 | "src": "/logo-48.png",
7 | "type": "image/png",
8 | "sizes": "48x48"
9 | },
10 | {
11 | "src": "/logo-96.png",
12 | "type": "image/png",
13 | "sizes": "96x96"
14 | },
15 | {
16 | "src": "/logo-192.png",
17 | "type": "image/png",
18 | "sizes": "192x192"
19 | }
20 | ],
21 | "start_url": "/",
22 | "display": "standalone",
23 | "orientation": "portrait",
24 | "theme_color": "#fff",
25 | "background_color": "#fff"
26 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tmpp-frontend",
3 | "version": "1.1.0-RC",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build"
8 | },
9 | "dependencies": {
10 | "ant-design-vue": "^1.3.10",
11 | "axios": "^0.19.0",
12 | "core-js": "^2.6.5",
13 | "js-base64": "^2.5.1",
14 | "moment": "^2.24.0",
15 | "vue": "^2.6.10",
16 | "vue-router": "^3.0.3",
17 | "vuex": "^3.0.1"
18 | },
19 | "devDependencies": {
20 | "@vue/cli-plugin-babel": "^3.7.0",
21 | "@vue/cli-service": "^3.7.0",
22 | "vue-template-compiler": "^2.5.21"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/components/ContentTitle.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{title}}
4 | {{subtitle}}
5 |
6 |
7 |
8 |
14 |
15 |
37 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | 哈信息教材采购系统
16 |
17 |
18 |
22 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/user.js:
--------------------------------------------------------------------------------
1 | import {Base64} from 'js-base64';
2 |
3 | let User = {};
4 | let loginUser = init();
5 |
6 | function init() {
7 | if (window.localStorage.getItem('authorization_token') === null) {
8 | return {};
9 | }
10 | try {
11 | return JSON.parse(JSON.parse(
12 | Base64.decode(
13 | window.localStorage.getItem('authorization_token')
14 | .split('.')[1]
15 | )
16 | ).loginUser);
17 | } catch (e) {
18 | window.localStorage.removeItem('authorization_token');
19 | return {};
20 | }
21 | }
22 |
23 | User.loginUser = loginUser;
24 | User.loginName = loginUser.name;
25 | User.userTypeName = function () {
26 | switch (loginUser.userType) {
27 | case "T":
28 | return '教师';
29 | case "A":
30 | return '教务处';
31 | case "O1":
32 | return "软件学院";
33 | case "O2":
34 | return "电子工程学院";
35 | case "O3":
36 | return "艺术设计学院";
37 | case "O4":
38 | return "商学院";
39 | case "O5":
40 | return "基础部";
41 | case "O6":
42 | return "素质教育中心";
43 | case "O7":
44 | return "体育教研室";
45 | default:
46 | return '未知角色'
47 | }
48 | };
49 | //T 教师 A 教务处 O 办公室主任
50 | User.user_is_teacher = loginUser.userType === 'T';
51 | User.user_is_aao = loginUser.userType === 'A';
52 | User.user_is_office_manager = ['O1', 'O2', 'O3', 'O4', 'O5', 'O6', 'O7'].indexOf(loginUser.userType) !== -1;
53 |
54 | User.install = function (Vue, options) {
55 | Vue.prototype.$user = User;
56 | };
57 |
58 | export default User;
59 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 哈尔滨信息工程学院教材管理系统
2 |
3 | [](https://github.com/HXCI-Studio/TMPP-FrontEnd/stargazers)
4 | [](https://github.com/HXCI-Studio/TMPP-FrontEnd/network/members)
5 | [](https://github.com/HXCI-Studio/TMPP-FrontEnd/watchers)
6 | [](https://github.com/HXCI-Studio?tab=followers)
7 |
8 | [](https://github.com/HXCI-Studio/TMPP-FrontEnd/issues)
9 | [](https://github.com/HXCI-Studio/TMPP-FrontEnd/blob/master/LICENSE)
10 | [](https://github.com/HXCI-Studio/TMPP-FrontEnd/commits)
11 | [](https://github.com/HXCI-Studio/TMPP-FrontEnd/releases)
12 | [](https://github.com/HXCI-Studio/TMPP-FrontEnd)
13 | [](http://hits.dwyl.io/HXCI-Studio/TMPP-FrontEnd)
14 | [](https://github.com/HXCI-Studio/TMPP-FrontEnd)
15 |
16 | ## 开源库
17 | - JavaScript框架:Vue.JS
18 | - CSS框架:Ant Design
19 | - 请求库:axios
20 | - 日期处理:moment
21 |
--------------------------------------------------------------------------------
/src/api.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Api 接口文件
3 | * date 2019-06-12
4 | * author itning
5 | * http://itning.top
6 | */
7 | 'use strict';
8 | //API地址
9 | export const BASE_URL = "http://localhost:8080";
10 | //登录接口
11 | export const CAS_LOGIN_URL = BASE_URL + "/login";
12 | //注销接口
13 | export const CAS_LOGOUT_URL = BASE_URL + "/logout";
14 |
15 | //以下所有Api必须带请求头Authorization
16 |
17 | export default {
18 | ///获取所有计划
19 | getExecutePlans:BASE_URL +'/execute_AllPlan',
20 | //获取未完成执行计划
21 | getUndonePlan: BASE_URL + '/undone_execute_plan',
22 | //下载执行计划
23 | getDownPlan: BASE_URL + '/down_execute_plan',
24 | //获取所有授课部门
25 | getTeachingDepartments: BASE_URL + '/teaching_departments',
26 | //获取教育层次
27 | getEducationalLevels: BASE_URL + '/educational_levels',
28 | //下载执行计划模板
29 | getDownloadPlanTemplate: BASE_URL + '/download_execute_plan_template',
30 | //提交执行计划
31 | postPlan: BASE_URL + '/execute_plan',
32 | //上传执行计划文件
33 | postPlanFile: BASE_URL + '/execute_plan_file',
34 | //全部审核通过
35 | postExaminationPassed: BASE_URL + '/examination_passed',
36 | //我的审核
37 | getMyReview: BASE_URL + '/my_review',
38 | //是否购买样书
39 | postBuySampleBook: BASE_URL + '/buy_sample_book',
40 | //驳回
41 | postTurnDown: BASE_URL + '/turn_down',
42 | //获取所有计划列表
43 | getPlans: BASE_URL + '/execute_plans',
44 | //删除执行计划
45 | deletePlans: BASE_URL + '/execute_plan',
46 | //获取所有学院
47 | getColleges: BASE_URL + '/colleges',
48 | //获取执行计划年
49 | getYear: BASE_URL + '/year',
50 | //获取计划学期
51 | getTerm: BASE_URL + '/term',
52 | //征订教材汇总表格
53 | getDownBookMaterials: BASE_URL + '/down_book_materials',
54 | //获取已完成执行计划
55 | getDonePlan: BASE_URL + '/done_execute_plan',
56 | //考试/考察/总体订书率表
57 | getSummaryTable: BASE_URL + '/summary_table',
58 | //出版社统计数量表
59 | getPublishingHouseStatistics: BASE_URL + '/publishing_house_statistics',
60 | //征订教材样书统计表
61 | getSubscriptionBook: BASE_URL + '/subscription_book',
62 | //教师领取教材汇总表
63 | getTeacherReceivingTextbook: BASE_URL + '/teacher_receiving_textbook',
64 | //学生班级领取教材反馈表
65 | getStudentTextbook: BASE_URL + '/student_textbook',
66 | //导出采购教材汇总表
67 | getProcurementTable: BASE_URL + '/procurement_table',
68 | //导出征订教材计划表
69 | getSubscriptionPlan: BASE_URL + '/subscription_plan',
70 | //查询所有折扣
71 | getDiscounts: BASE_URL + '/discounts',
72 | //添加折扣
73 | postDiscount: BASE_URL + '/discount',
74 | //删除折扣
75 | deleteDiscount: BASE_URL + '/discount',
76 | //修改折扣
77 | patchDiscount: BASE_URL + '/discount',
78 | //办公室主任征订教材计划统计表
79 | getTextbookPlanStatistics: BASE_URL + '/textbook_execute_plan_statistics',
80 | //办公室主任我的审核
81 | getDirectorReview: BASE_URL + '/director_review',
82 | //办公室主任驳回
83 | postOfficeTurnDown: BASE_URL + '/office_turn_down',
84 | //办公室主任全部审核通过
85 | postAllPassed: BASE_URL + '/all_passed',
86 | //获取课程名称
87 | getCourseTitles: BASE_URL + '/courseTitles',
88 | //提交购书信息
89 | postBookPurchaseInformation: BASE_URL + '/book_purchase_information',
90 | //我的购书
91 | getPurchaseBook: BASE_URL + '/purchase_book',
92 | //修改购书
93 | patchPurchase: BASE_URL + '/purchase',
94 | }
95 |
--------------------------------------------------------------------------------
/src/router.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import Vuex from './store'
4 | import {CAS_LOGIN_URL} from "./api";
5 |
6 | Vue.use(Router)
7 |
8 | let router = new Router({
9 | mode: 'history',
10 | base: process.env.BASE_URL,
11 | routes: [
12 | {
13 | path: '/',
14 | redirect: '/plan_list'
15 | },
16 | {
17 | path: '/plan_list',
18 | name: 'planList',
19 | component: () => import(/* webpackChunkName: "planList" */ './views/aao/PlanList.vue')
20 | },
21 | {
22 | path: '/new_plan',
23 | name: 'newPlan',
24 | component: () => import(/* webpackChunkName: "newPlan" */ './views/aao/NewPlan.vue')
25 | },
26 | {
27 | path: '/export',
28 | name: 'export',
29 | component: () => import(/* webpackChunkName: "export" */ './views/aao/Export.vue')
30 | },
31 | {
32 | path: '/discount',
33 | name: 'discount',
34 | component: () => import(/* webpackChunkName: "discount" */ './views/aao/Discount.vue')
35 | },
36 | {
37 | path: '/buy',
38 | name: 'buy',
39 | component: () => import(/* webpackChunkName: "buy" */ './views/teacher/Buy.vue')
40 | },
41 | {
42 | path: '/add',
43 | name: 'add',
44 | component: () => import(/* webpackChunkName: "add" */ './views/teacher/Add.vue')
45 | },
46 | {
47 | path: '/review',
48 | name: 'review',
49 | component: () => import(/* webpackChunkName: "review" */ './views/aao/Review.vue')
50 | },
51 | {
52 | path: '/office_review',
53 | name: 'officeReview',
54 | component: () => import(/* webpackChunkName: "officeReview" */ './views/om/Review.vue')
55 | },
56 | {
57 | path: '/token/:id',
58 | name: 'token',
59 | component: () => import(/* webpackChunkName: "planList" */ './views/aao/PlanList.vue'),
60 | beforeEnter: (to, from, next) => {
61 | window.localStorage.setItem('authorization_token', to.params.id);
62 | window.location.href = window.location.protocol + '//' + window.location.host;
63 | next(false);
64 | }
65 | },
66 | {
67 | path: "*",
68 | redirect: "/"
69 | }
70 | ]
71 | });
72 | //T 教师 A 教务处 O 办公室主任
73 | const A = ['plan_list', 'new_plan', 'export', 'discount', 'review'];
74 | const O = ['office_review'];
75 | const T = ['buy', 'add'];
76 |
77 | /**
78 | * 检查用户是否有当前路由权限
79 | * @param path 路径
80 | * @returns {boolean} 是否有权限
81 | */
82 | function havePermission(path) {
83 | const p = path.replace(/[^a-zA-Z_]/g, '');
84 | switch (Vue.prototype.$user.loginUser.userType) {
85 | //教务处
86 | case 'A':
87 | return A.includes(p);
88 | //办公室主任
89 | case 'O1':
90 | case 'O2':
91 | case 'O3':
92 | case 'O4':
93 | case 'O5':
94 | case 'O6':
95 | case 'O7':
96 | return O.includes(p);
97 | //教师
98 | case 'T':
99 | return T.includes(p);
100 | }
101 | }
102 |
103 | /***
104 | * 跳转到用户正确的路径
105 | * @param next 路由回调
106 | */
107 | function route2TruePath(next) {
108 | if (Vue.prototype.$user.user_is_office_manager) {
109 | next('/office_review');
110 | } else if (Vue.prototype.$user.user_is_teacher) {
111 | next('/buy');
112 | } else if (Vue.prototype.$user.user_is_aao) {
113 | next('/plan_list');
114 | } else {
115 | next(false);
116 | }
117 | }
118 |
119 | /**
120 | * 路由全局守卫
121 | * 1.如果Url以'/token'开头,放行
122 | * 2.如果localStorage中last_path key 有值则放弃当前路由跳至last_path路径
123 | */
124 | router.beforeEach((to, from, next) => {
125 | if (!to.path.startsWith('/token') && window.localStorage.getItem('authorization_token') == null) {
126 | window.location.href = CAS_LOGIN_URL;
127 | return;
128 | }
129 | if (to.path.startsWith('/token')) {
130 | next();
131 | return;
132 | }
133 | if (!havePermission(to.path)) {
134 | route2TruePath(next);
135 | return;
136 | }
137 | let path = window.localStorage.getItem('last_path');
138 | if (path !== null) {
139 | window.localStorage.removeItem('last_path');
140 | next(path);
141 | } else {
142 | next();
143 | }
144 | });
145 | /***
146 | * 全局后置钩子
147 | */
148 | router.afterEach((to, from) => {
149 | Vuex.state.now_path = to.path;
150 | });
151 |
152 | export default router;
153 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
![logo img]()
11 |
12 |
13 |
14 |
15 | 新增计划
16 |
17 |
18 |
19 | 我的审核
20 |
21 |
22 |
23 | 计划列表
24 |
25 |
26 |
27 | 导出表格
28 |
29 |
30 |
31 | 折扣管理
32 |
33 |
34 |
36 |
37 | 我的审核
38 |
39 |
40 |
41 |
42 |
43 | 我的购书
44 |
45 |
46 |
47 | 填写购书信息
48 |
49 |
50 |
51 |
52 |
53 |
54 | collapsed = !collapsed"
58 | />
59 |
60 |
61 | {{loginUser}}
62 |
63 |
64 |
65 |
66 | 注销登录
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
119 |
120 |
145 |
146 |
159 |
--------------------------------------------------------------------------------
/src/views/aao/PlanList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 全部
7 | 进行中
8 | 已完成
9 |
10 |
11 |
20 |
21 | 删除
22 | 下载执行计划
23 |
24 |
25 |
26 |
27 |
28 |
29 |
195 |
196 |
201 |
--------------------------------------------------------------------------------
/src/views/aao/Discount.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
新增折扣
6 |
8 |
9 |
10 |
13 |
14 |
15 |
handleChange(e.target.value, record.id, 'discount')"/>
17 | {{text}}
18 |
19 |
20 |
21 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
186 |
187 |
190 |
--------------------------------------------------------------------------------
/src/components/TeacherModifyBookModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | placeholder="选择课程名称">
7 |
8 | {{courseTitle.courseCode+'-'+courseTitle.courseName}}
9 |
10 |
11 |
12 |
13 |
14 | 是
15 | 否
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 出版
28 | 自编
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
44 | {{discount.discount}}
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
69 |
70 | 提交
71 |
72 |
73 |
74 |
75 |
76 |
170 |
171 |
174 |
--------------------------------------------------------------------------------
/src/axios.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import Vue from 'vue'
3 | import {CAS_LOGIN_URL} from "./api";
4 | //错误吐司
5 | const showErrorToast = function (title, msg, duration = 4.5) {
6 | Vue.prototype.$notification['error']({
7 | message: title,
8 | description: msg,
9 | duration: duration
10 | });
11 | };
12 | //一次显示错误吐司
13 | let show = false;
14 | const onceToast = function (msg) {
15 | if (show) {
16 | return;
17 | }
18 | showErrorToast('注意:', msg);
19 | show = true;
20 | };
21 |
22 | //12s超时
23 | let instance = axios.create({timeout: 1000 * 12});
24 |
25 | //请求拦截器
26 | instance.interceptors.request.use((request) => {
27 | let token = window.localStorage.getItem('authorization_token');
28 | if (token !== undefined) {
29 | request.headers = {
30 | "Authorization": token,
31 | "Accept": "application/json"
32 | };
33 | } else {
34 | request.headers = {"Accept": "application/json"};
35 | }
36 | return request;
37 |
38 | }, function (error) {
39 | // Do something with request error
40 | return Promise.reject(error);
41 | });
42 |
43 | // 响应拦截器
44 | instance.interceptors.response.use(
45 | response => {
46 | return Promise.resolve(response);
47 | },
48 | // 服务器状态码不是200的情况
49 | error => {
50 | if (error.response === undefined) {
51 | showErrorToast('网络异常', '请检查网络连接状态后再试', null);
52 | return Promise.reject(error);
53 | }
54 | if (error.response.status) {
55 | switch (error.response.status) {
56 | case 401:
57 | window.localStorage.setItem('last_path', window.location.pathname);
58 | setTimeout(() => {
59 | window.location.href = CAS_LOGIN_URL;
60 | }, 2000);
61 | onceToast(error.response.data.msg);
62 | return;
63 | case 403:
64 | console.warn('权限不足');
65 | break;
66 | case 404:
67 | console.warn('请求URL不存在');
68 | break;
69 | case 500:
70 | console.warn('服务器错误');
71 | break;
72 | case 503:
73 | console.warn('服务器错误');
74 | break;
75 | default:
76 | console.warn(error);
77 | }
78 | return Promise.reject(error);
79 | }
80 | }
81 | );
82 |
83 | const Method = {GET: 0, POST: 1, DELETE: 2, UPDATE: 3, PUT: 4, PATCH: 5};
84 |
85 | export function Get(url) {
86 | return new _request(url, Method.GET);
87 | }
88 |
89 | export function Del(url) {
90 | return new _request(url, Method.DELETE);
91 | }
92 |
93 | export function Post(url) {
94 | return new _request(url, Method.POST);
95 | }
96 |
97 | export function Patch(url) {
98 | return new _request(url, Method.PATCH);
99 | }
100 |
101 | export function Download(url, fileName) {
102 | instance.get(url, {
103 | responseType: 'blob' //指定返回数据的格式为blob
104 | }).then(response => {
105 | let url = window.URL.createObjectURL(response.data);
106 | let a = document.createElement("a");
107 | document.body.appendChild(a);
108 | a.href = url;
109 | a.download = fileName(response.headers);
110 | a.click();
111 | window.URL.revokeObjectURL(url);
112 | }).catch(error => {
113 | if (error.response !== undefined) {
114 | console.warn(error);
115 | showErrorToast("下载失败:", error.toString());
116 | }
117 | });
118 | }
119 |
120 | function _request(url, method) {
121 | this.method = method;
122 | this.url = url;
123 | this.code = 200;
124 | this.startMsg = '错误:';
125 | }
126 |
127 | _request.prototype.withErrorStartMsg = function (msg) {
128 | this.startMsg = msg;
129 | return this;
130 | };
131 |
132 | _request.prototype.withSuccessCode = function (code) {
133 | this.code = code;
134 | return this;
135 | };
136 |
137 | _request.prototype.withURLSearchParams = function (params) {
138 | let urlSearchParams = new URLSearchParams();
139 | for (let p in params) {
140 | if (params.hasOwnProperty(p)) {
141 | let v = params[p];
142 | urlSearchParams.append(p, v);
143 | }
144 | }
145 | this.urlSearchParams = urlSearchParams;
146 | return this;
147 | };
148 |
149 | _request.prototype.withFormData = function (params, enableUploadProgress = true, uploadProgress) {
150 | let formData = new FormData();
151 | for (let p in params) {
152 | if (params.hasOwnProperty(p)) {
153 | let v = params[p];
154 | formData.append(p, v);
155 | }
156 | }
157 | this.formData = formData;
158 | this.enableUploadProgress = enableUploadProgress;
159 | this.uploadProgress = uploadProgress;
160 | return this;
161 | };
162 |
163 | _request.prototype.doAfter = function (fn) {
164 | this.doAfterFun = fn;
165 | return this;
166 | };
167 |
168 | _request.prototype.do = function (fn) {
169 | let that = this;
170 | let promise = null;
171 | switch (this.method) {
172 | case Method.GET:
173 | promise = instance.get(this.url);
174 | break;
175 | case Method.DELETE:
176 | if (this.urlSearchParams !== undefined) {
177 | promise = instance.delete(this.url, {data: this.urlSearchParams});
178 | } else if (this.formData !== undefined) {
179 | promise = instance.delete(this.url, {
180 | data: this.formData,
181 | headers: {'content-type': 'multipart/form-data'}
182 | });
183 | } else {
184 | promise = instance.delete(this.url);
185 | }
186 | break;
187 | case Method.POST:
188 | if (this.urlSearchParams !== undefined) {
189 | promise = instance.post(this.url, this.urlSearchParams);
190 | } else if (this.formData !== undefined) {
191 | if (this.enableUploadProgress === false) {
192 | promise = instance.post(this.url, this.formData, {headers: {'content-type': 'multipart/form-data'}});
193 | } else {
194 | const uploadProgress = this.uploadProgress;
195 | let config = {
196 | headers: {'content-type': 'multipart/form-data'},
197 | onUploadProgress: progressEvent => {
198 | let progress = progressEvent.loaded / progressEvent.total * 100 | 0;
199 | uploadProgress(progress);
200 | }
201 | };
202 | promise = instance.post(this.url, this.formData, config);
203 | }
204 | } else {
205 | promise = instance.post(this.url);
206 | }
207 | break;
208 | case Method.PATCH:
209 | if (this.urlSearchParams !== undefined) {
210 | promise = instance.patch(this.url, this.urlSearchParams);
211 | } else if (this.formData !== undefined) {
212 | promise = instance.patch(this.url, this.formData, {headers: {'content-type': 'multipart/form-data'}});
213 | } else {
214 | promise = instance.patch(this.url);
215 | }
216 | break;
217 | default:
218 | return Promise.reject('none switch found of ' + this.method);
219 | }
220 | promise
221 | .then(response => {
222 | if (response.status === that.code) {
223 | fn(response)
224 | } else {
225 | showErrorToast(that.startMsg, response.data.msg);
226 | }
227 | })
228 | .catch(error => {
229 | if (error.response !== undefined) {
230 | showErrorToast(that.startMsg, error.response.data.msg);
231 | }
232 | })
233 | .then(() => {
234 | if (that.doAfterFun !== undefined) {
235 | that.doAfterFun();
236 | }
237 | });
238 | return this;
239 | };
240 |
241 | export default instance;
242 |
--------------------------------------------------------------------------------
/src/views/aao/NewPlan.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
11 | -
12 |
14 |
15 |
16 |
17 | 第一学期
18 | 第二学期
19 |
20 |
21 |
22 |
24 |
26 | {{teaching_department.name}}
27 |
28 |
29 |
30 |
31 |
33 |
35 | {{educational_levels.educationalLevel}}
36 |
37 |
38 |
39 |
40 |
43 |
44 |
45 | 选择文件(支持扩展名:.xls .xlsx)
46 |
47 |
48 | 下载征订计划模板
49 |
50 |
51 | 提交
52 |
53 |
54 |
55 |
56 |
57 |
58 |
228 |
229 |
232 |
--------------------------------------------------------------------------------
/src/views/teacher/Buy.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 征订计划:
6 |
8 | {{planItem.name}}
9 |
10 |
11 |
下载征订教材计划单
12 |
21 |
22 | 修改
23 |
24 |
25 |
26 |
28 |
30 |
31 |
32 |
33 |
34 |
293 |
294 |
297 |
--------------------------------------------------------------------------------
/src/views/om/Review.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 征订计划:
6 |
8 | {{planItem.name}}
9 |
10 |
11 |
全部审核通过
12 |
导出征订教材计划统计表
13 |
22 |
23 | 驳回
24 |
25 |
26 |
27 |
28 |
29 |
30 |
294 |
295 |
300 |
--------------------------------------------------------------------------------
/mock.json:
--------------------------------------------------------------------------------
1 | {
2 | "teaching_departments": {
3 | "获取所有授课部门": 1,
4 | "code": 200,
5 | "msg": "查询成功",
6 | "data": [
7 | {
8 | "id": "1",
9 | "name": "软件学院"
10 | },
11 | {
12 | "id": "2",
13 | "name": "商学院"
14 | }
15 | ]
16 | },
17 | "educational_levels": {
18 | "获取教育层次": 1,
19 | "code": 200,
20 | "msg": "查询成功",
21 | "data": [
22 | {
23 | "id": "1",
24 | "name": "本科"
25 | },
26 | {
27 | "id": "2",
28 | "name": "高职"
29 | }
30 | ]
31 | },
32 | "undone_plan": {
33 | "获取未完成执行计划": 1,
34 | "code": 200,
35 | "msg": "查询成功",
36 | "data": [
37 | {
38 | "id": "1",
39 | "year": "2018-2019",
40 | "term": 1,
41 | "teachingDepartment": "软件学院",
42 | "educationalLevel": "本科"
43 | },
44 | {
45 | "id": "2",
46 | "year": "2018-2019",
47 | "term": 2,
48 | "teachingDepartment": "软件学院",
49 | "educationalLevel": "本科"
50 | }
51 | ]
52 | },
53 | "plans": {
54 | "获取所有计划列表": 1,
55 | "code": 200,
56 | "msg": "获取计划列表成功",
57 | "data": {
58 | "pageNum": 1,
59 | "pageSize": 2,
60 | "size": 5,
61 | "orderBy": null,
62 | "startRow": 1,
63 | "endRow": 5,
64 | "total": 11,
65 | "pages": 3,
66 | "list": [
67 | {
68 | "id": "1",
69 | "year": "2018-2019",
70 | "term": 1,
71 | "teachingDepartment": "软件学院",
72 | "educationalLevel": "本科",
73 | "startTime": "2017-10-01 12:00",
74 | "endTime": "2017-10-01 12:00",
75 | "approvalStatus": "进行中"
76 | },
77 | {
78 | "id": "2",
79 | "year": "2018-2019",
80 | "term": 1,
81 | "teachingDepartment": "软件学院",
82 | "educationalLevel": "本科",
83 | "startTime": "2017-10-01 12:00",
84 | "endTime": "2017-10-01 12:00",
85 | "approvalStatus": "已完成"
86 | }
87 | ],
88 | "prePage": 0,
89 | "nextPage": 2,
90 | "isFirstPage": true,
91 | "isLastPage": false,
92 | "hasPreviousPage": false,
93 | "hasNextPage": true,
94 | "navigatePages": 8,
95 | "navigatepageNums": [
96 | 1,
97 | 2,
98 | 3
99 | ],
100 | "navigateFirstPage": 1,
101 | "navigateLastPage": 3,
102 | "firstPage": 1,
103 | "lastPage": 3
104 | }
105 | },
106 | "done_plan": {
107 | "获取已完成执行计划": 1,
108 | "code": 200,
109 | "msg": "查询成功",
110 | "data": [
111 | {
112 | "id": "1",
113 | "year": "2018-2019",
114 | "term": 1,
115 | "teachingDepartment": "软件学院",
116 | "educationalLevel": "本科"
117 | },
118 | {
119 | "id": "2",
120 | "year": "2018-2019",
121 | "term": 2,
122 | "teachingDepartment": "软件学院",
123 | "educationalLevel": "本科"
124 | }
125 | ]
126 | },
127 | "colleges": {
128 | "获取所有学院": 1,
129 | "code": 200,
130 | "msg": "查询成功",
131 | "data": [
132 | {
133 | "id": "1",
134 | "name": "软件学院"
135 | },
136 | {
137 | "id": "2",
138 | "name": "商学院"
139 | }
140 | ]
141 | },
142 | "year": {
143 | "获取执行计划年": 1,
144 | "code": 200,
145 | "msg": "查询成功",
146 | "data": [
147 | "2018-2019",
148 | "2019-2020"
149 | ]
150 | },
151 | "term": {
152 | "获取计划学期": 1,
153 | "code": 200,
154 | "msg": "查询成功",
155 | "data": [
156 | 1,
157 | 2
158 | ],
159 | "id": "2018-2019"
160 | },
161 | "my_review": {
162 | "教务处我的审核": 1,
163 | "code": 200,
164 | "msg": "查询成功",
165 | "data": {
166 | "pageNum": 1,
167 | "pageSize": 2,
168 | "size": 5,
169 | "orderBy": null,
170 | "startRow": 1,
171 | "endRow": 5,
172 | "total": 11,
173 | "pages": 3,
174 | "list": [
175 | {
176 | "id": "1",
177 | "courseCode": "B001",
178 | "courseTitle": 1,
179 | "isBookPurchase": 0,
180 | "isbn": "9789993700142",
181 | "textbookName": "阿里技术参考图册",
182 | "textbookCategory": "出版",
183 | "press": "清华大学出版社",
184 | "author": "某某",
185 | "unitPrice": 15.00,
186 | "teacherBookNumber": 1,
187 | "discount": 0.76,
188 | "awardInformation": "获奖信息",
189 | "publicationDate": "2018-09",
190 | "subscriber": "周老师",
191 | "subscriberNumber": "13333333333",
192 | "approvalStatus": "审核通过",
193 | "isBuyBook": true
194 | },
195 | {
196 | "id": "2",
197 | "courseCode": "B001",
198 | "courseTitle": 1,
199 | "isBookPurchase": 0,
200 | "isbn": "9789993700142",
201 | "textbookName": "阿里技术参考图册",
202 | "textbookCategory": "出版",
203 | "press": "清华大学出版社",
204 | "author": "某某",
205 | "unitPrice": 15.00,
206 | "teacherBookNumber": 1,
207 | "discount": 0.76,
208 | "awardInformation": "获奖信息",
209 | "publicationDate": "2018-09",
210 | "subscriber": "周老师",
211 | "subscriberNumber": "13333333333",
212 | "approvalStatus": "审核通过",
213 | "isBuyBook": true
214 | }
215 | ],
216 | "prePage": 0,
217 | "nextPage": 2,
218 | "isFirstPage": true,
219 | "isLastPage": false,
220 | "hasPreviousPage": false,
221 | "hasNextPage": true,
222 | "navigatePages": 8,
223 | "navigatepageNums": [
224 | 1,
225 | 2,
226 | 3
227 | ],
228 | "navigateFirstPage": 1,
229 | "navigateLastPage": 3,
230 | "firstPage": 1,
231 | "lastPage": 3
232 | }
233 | },
234 | "discounts": {
235 | "查询所有折扣": 1,
236 | "code": 200,
237 | "msg": "查询成功",
238 | "data": {
239 | "pageNum": 1,
240 | "pageSize": 2,
241 | "size": 5,
242 | "orderBy": null,
243 | "startRow": 1,
244 | "endRow": 5,
245 | "total": 11,
246 | "pages": 3,
247 | "list": [
248 | {
249 | "id": "1",
250 | "discount": 0.76
251 | },
252 | {
253 | "id": "2",
254 | "discount": 0.76
255 | }
256 | ],
257 | "prePage": 0,
258 | "nextPage": 2,
259 | "isFirstPage": true,
260 | "isLastPage": false,
261 | "hasPreviousPage": false,
262 | "hasNextPage": true,
263 | "navigatePages": 8,
264 | "navigatepageNums": [
265 | 1,
266 | 2,
267 | 3
268 | ],
269 | "navigateFirstPage": 1,
270 | "navigateLastPage": 3,
271 | "firstPage": 1,
272 | "lastPage": 3
273 | }
274 | },
275 | "director_review": {
276 | "办公室主任我的审核": 1,
277 | "code": 200,
278 | "msg": "查询成功",
279 | "data": {
280 | "pageNum": 1,
281 | "pageSize": 2,
282 | "size": 5,
283 | "orderBy": null,
284 | "startRow": 1,
285 | "endRow": 5,
286 | "total": 11,
287 | "pages": 3,
288 | "list": [
289 | {
290 | "id": "1",
291 | "courseCode": "B001",
292 | "courseTitle": 1,
293 | "isBookPurchase": 0,
294 | "isbn": "9789993700142",
295 | "textbookName": "阿里技术参考图册",
296 | "textbookCategory": "出版",
297 | "press": "清华大学出版社",
298 | "author": "某某",
299 | "unitPrice": 15.00,
300 | "teacherBookNumber": 1,
301 | "discount": 0.76,
302 | "awardInformation": "获奖信息",
303 | "publicationDate": "2018-09",
304 | "subscriber": "周老师",
305 | "subscriberNumber": "13333333333",
306 | "approvalStatus": "审核通过"
307 | },
308 | {
309 | "id": "2",
310 | "courseCode": "B001",
311 | "courseTitle": 1,
312 | "isBookPurchase": 0,
313 | "isbn": "9789993700142",
314 | "textbookName": "阿里技术参考图册",
315 | "textbookCategory": "出版",
316 | "press": "清华大学出版社",
317 | "author": "某某",
318 | "unitPrice": 15.00,
319 | "teacherBookNumber": 1,
320 | "discount": 0.76,
321 | "awardInformation": "获奖信息",
322 | "publicationDate": "2018-09",
323 | "subscriber": "周老师",
324 | "subscriberNumber": "13333333333",
325 | "approvalStatus": "审核通过"
326 | }
327 | ],
328 | "prePage": 0,
329 | "nextPage": 2,
330 | "isFirstPage": true,
331 | "isLastPage": false,
332 | "hasPreviousPage": false,
333 | "hasNextPage": true,
334 | "navigatePages": 8,
335 | "navigatepageNums": [
336 | 1,
337 | 2,
338 | 3
339 | ],
340 | "navigateFirstPage": 1,
341 | "navigateLastPage": 3,
342 | "firstPage": 1,
343 | "lastPage": 3
344 | }
345 | },
346 | "purchase_book": {
347 | "我的购书": 1,
348 | "code": 200,
349 | "msg": "查询成功",
350 | "data": {
351 | "pageNum": 1,
352 | "pageSize": 2,
353 | "size": 5,
354 | "orderBy": null,
355 | "startRow": 1,
356 | "endRow": 5,
357 | "total": 11,
358 | "pages": 3,
359 | "list": [
360 | {
361 | "id": "1",
362 | "courseCode": "B001",
363 | "courseTitle": 1,
364 | "isBookPurchase": 0,
365 | "isbn": "9789993700142",
366 | "textbookName": "阿里技术参考图册",
367 | "textbookCategory": "出版",
368 | "press": "清华大学出版社",
369 | "author": "某某",
370 | "unitPrice": 15.00,
371 | "teacherBookNumber": 1,
372 | "discount": 0.76,
373 | "awardInformation": "获奖信息",
374 | "publicationDate": "2018-09",
375 | "subscriber": "周老师",
376 | "subscriberNumber": "13333333333",
377 | "approvalStatus": "审核通过"
378 | },
379 | {
380 | "id": "2",
381 | "courseCode": "B001",
382 | "courseTitle": 1,
383 | "isBookPurchase": 0,
384 | "isbn": "9789993700142",
385 | "textbookName": "阿里技术参考图册",
386 | "textbookCategory": "出版",
387 | "press": "清华大学出版社",
388 | "author": "某某",
389 | "unitPrice": 15.00,
390 | "teacherBookNumber": 1,
391 | "discount": 0.76,
392 | "awardInformation": "获奖信息",
393 | "publicationDate": "2018-09",
394 | "subscriber": "周老师",
395 | "subscriberNumber": "13333333333",
396 | "approvalStatus": "审核通过"
397 | }
398 | ],
399 | "prePage": 0,
400 | "nextPage": 2,
401 | "isFirstPage": true,
402 | "isLastPage": false,
403 | "hasPreviousPage": false,
404 | "hasNextPage": true,
405 | "navigatePages": 8,
406 | "navigatepageNums": [
407 | 1,
408 | 2,
409 | 3
410 | ],
411 | "navigateFirstPage": 1,
412 | "navigateLastPage": 3,
413 | "firstPage": 1,
414 | "lastPage": 3
415 | }
416 | },
417 | "courseTitles": {
418 | "获取课程名称": 1,
419 | "code": 200,
420 | "msg": "获取课程名称成功",
421 | "data": [
422 | {
423 | "id": "1",
424 | "courseCode": "B001",
425 | "courseTitle": 1
426 | },
427 | {
428 | "id": "2",
429 | "courseCode": "B001",
430 | "courseTitle": 1
431 | }
432 | ]
433 | }
434 | }
--------------------------------------------------------------------------------
/src/views/aao/Export.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 学院/开设院系部:
6 |
7 |
8 | {{college.name}}
9 |
10 |
11 |
12 |
14 | {{teachingDepartment.name}}
15 |
16 |
17 |
18 | 学年:
19 |
20 | {{year}}
21 |
22 | 学期:
23 |
24 | {{term===0?'第一学期':'第二学期'}}
25 |
26 |
27 |
导出征订教材汇总表 ↓
29 |
30 |
31 |
![征订教材汇总表图片]()
32 |
33 |
34 | 征订计划:
35 |
36 | {{executePlanItem.name}}
37 |
38 |
39 |
40 |
41 | 导出采购教材汇总表↓
42 |
43 |
44 |
![采购教材汇总图片]()
45 |
46 |
47 |
48 | 征订计划:
49 |
50 | {{planItem.name}}
51 |
52 |
53 |
54 |
55 | 导出考试/考查/总体订书率表 ↓
56 |
57 |
58 |
![考试/考查/总体订书率图片]()
59 |
60 |
61 | 导出出版社统计数量表 ↓
62 |
63 |
64 |
![出版社统计数量图片]()
65 |
66 |
67 | 导出征订教材样书汇总表 ↓
68 |
69 |
70 |
![征订教材样书汇总图片]()
71 |
72 |
73 | 导出教师领取教材汇总表 ↓
74 |
75 |
76 |
![教师领取教材汇总图片]()
77 |
78 |
79 | 导出学生班级领取教材反馈表 ↓
80 |
81 |
82 |
![学生班级领取教材反馈图片]()
83 |
84 |
85 |
86 |
87 |
88 |
314 |
315 |
320 |
--------------------------------------------------------------------------------
/src/views/teacher/Add.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{planItem.name}}
9 |
10 |
11 | 下载该征订计划
12 |
13 |
14 |
17 |
19 | {{courseTitle.courseCode+'-'+courseTitle.courseName}}
20 |
21 |
22 |
23 |
24 |
25 | 是
26 | 否
27 |
28 |
29 |
30 |
31 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | 出版
40 | 自编
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
52 |
53 |
54 |
55 |
56 | {{discount.discount}}
57 |
58 |
59 |
60 |
61 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
76 |
77 |
78 |
85 |
86 | 提交
87 |
88 |
89 |
90 |
91 |
92 |
93 |
298 |
299 |
302 |
--------------------------------------------------------------------------------
/src/views/aao/Review.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 征订计划:
6 |
8 | {{planItem.name}}
9 |
10 |
11 |
全部审核通过
12 |
导出采购教材汇总表
13 |
22 |
23 |
27 | 是
28 | 否
29 |
30 |
31 |
32 | 驳回
34 |
35 |
36 |
37 |
38 |
39 |
40 |
326 |
327 |
333 |
350 |
--------------------------------------------------------------------------------