Commit f20c48c9a8e9fec3a80fe21ff036fa894424f267

Authored by 梁保满
1 parent 87053bc8

集团管理员添加发卡记录,并添加报表导出

src/api/apis/apis.js
... ... @@ -490,6 +490,7 @@ export default {
490 490 url: setUpUrls.teacherTemplate,
491 491 method: "POST",
492 492 data,
  493 + responseType: 'arraybuffer',
493 494 });
494 495 },
495 496 // 教师导出
... ... @@ -694,6 +695,15 @@ export default {
694 695 data,
695 696 });
696 697 },
  698 + // 发卡数据导出
  699 + exportClickersLog(data) {
  700 + return service({
  701 + url: setUpUrls.exportClickersLog,
  702 + method: "POST",
  703 + data,
  704 + responseType: 'arraybuffer',
  705 + });
  706 + },
697 707  
698 708 /**
699 709 * 集团管理员-学校管理
... ...
src/api/urls/apis.js
... ... @@ -172,6 +172,8 @@ export default {
172 172 exportUsageAnalysis: "/api_html/school/manager/exportUsageAnalysis",
173 173 // 发卡应用下载
174 174 latestClickersApp: "/api_html/school/manager/latestClickersApp",
  175 + // 发卡导出
  176 + exportClickersLog: "/api_html/school/manager/exportClickersLog",
175 177  
176 178  
177 179 // 查询区域列表
... ...
src/assets/nav/setUpConglomerate.png

6.65 KB | W: | H:

6.32 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
src/views/index/mainIndex.vue
... ... @@ -117,6 +117,10 @@
117 117 <p class="p1">使用分析</p>
118 118 <p class="p2">按学校、学段统计使用频率。</p>
119 119 </div>
  120 + <div class="text" v-else-if="item.path == '/card'">
  121 + <p class="p1">发卡记录</p>
  122 + <p class="p2">查看发卡、换卡记录信息。</p>
  123 + </div>
120 124 </li>
121 125 </template>
122 126 </ul>
... ... @@ -157,78 +161,77 @@
157 161 </li>
158 162 </template>
159 163 </ul>
160   - <ul class="nav-list" v-if="type == 'ROLE_PERSONAL'">
161   - <li class="nav-item item1" @click="links('/examinationPaper')">
162   - <img class="icon" src="../../assets/nav/setUpAccount.png" alt="" />
163   - <div class="text">
164   - <p class="p1">备题组卷</p>
165   - <p class="p2" v-if="dataInfo.paperCount">
166   - 管理 {{ dataInfo.paperCount }}套答题卡,
167   - </p>
168   - </div>
169   - </li>
170   - <li class="nav-item item1" @click="links('/setUpStudent')">
171   - <img class="icon" src="../../assets/nav/setUpSchool.png" alt="" />
172   - <div class="text">
173   - <p class="p1">班级名单</p>
174   - <p class="p2" v-if="dataInfo.classCount">
175   - 管理{{ dataInfo.classCount }}个班级的学生名单,
176   - </p>
177   - </div>
178   - </li>
179   - <li class="nav-item item2" @click="links('/portrait')">
180   - <img class="icon" src="../../assets/nav/device.png" alt="" />
  164 + <ul class="nav-list" v-if="type == 'ROLE_PERSONAL'">
  165 + <li class="nav-item item1" @click="links('/examinationPaper')">
  166 + <img class="icon" src="../../assets/nav/setUpAccount.png" alt="" />
  167 + <div class="text">
  168 + <p class="p1">备题组卷</p>
  169 + <p class="p2" v-if="dataInfo.paperCount">
  170 + 管理 {{ dataInfo.paperCount }}套答题卡,
  171 + </p>
  172 + </div>
  173 + </li>
  174 + <li class="nav-item item1" @click="links('/setUpStudent')">
  175 + <img class="icon" src="../../assets/nav/setUpSchool.png" alt="" />
  176 + <div class="text">
  177 + <p class="p1">班级名单</p>
  178 + <p class="p2" v-if="dataInfo.classCount">
  179 + 管理{{ dataInfo.classCount }}个班级的学生名单,
  180 + </p>
  181 + </div>
  182 + </li>
  183 + <li class="nav-item item2" @click="links('/portrait')">
  184 + <img class="icon" src="../../assets/nav/device.png" alt="" />
  185 + <div class="text">
  186 + <p class="p1">学生画像</p>
  187 + <p class="p2" v-if="dataInfo.stationCount">
  188 + 共分析{{ dataInfo.stationCount }}名学生成绩
  189 + </p>
  190 + </div>
  191 + </li>
  192 + <li class="item3">
  193 + <div class="nav-item item1 item-child2" @click="links('/ask')">
  194 + <img class="icon" src="../../assets/nav/card.png" alt="" />
  195 + <p class="p1">随堂问报表</p>
  196 + <p class="p2" v-if="dataInfo.classPeriodCount">
  197 + 对{{ dataInfo.classPeriodCount }}套随堂问答题记录分析
  198 + </p>
  199 + </div>
  200 + <div class="nav-item item1 item-child3" @click="links('/test')">
  201 + <img class="icon" src="../../assets/nav/analysis.png" alt="" />
  202 + <p class="p1">即时测报表</p>
  203 + <p class="p2" v-if="dataInfo.examCount">
  204 + 对{{ dataInfo.examCount }}套即时测答题记录分析
  205 + </p>
  206 + </div>
  207 + <div class="nav-item item1 item-child1" @click="links('/down')">
  208 + <img class="icon" src="../../assets/nav/down.png" alt="" />
181 209 <div class="text">
182   - <p class="p1">学生画像</p>
183   - <p class="p2" v-if="dataInfo.stationCount">
184   - 共分析{{ dataInfo.stationCount }}名学生成绩
185   - </p>
186   - </div>
187   - </li>
188   - <li class="item3">
189   - <div class="nav-item item1 item-child2" @click="links('/ask')">
190   - <img class="icon" src="../../assets/nav/card.png" alt="" />
191   - <p class="p1">随堂问报表</p>
192   - <p class="p2" v-if="dataInfo.classPeriodCount">
193   - 对{{ dataInfo.classPeriodCount }}套随堂问答题记录分析
194   - </p>
195   - </div>
196   - <div class="nav-item item1 item-child3" @click="links('/test')">
197   - <img class="icon" src="../../assets/nav/analysis.png" alt="" />
198   - <p class="p1">即时测报表</p>
199   - <p class="p2" v-if="dataInfo.examCount">
200   - 对{{ dataInfo.examCount }}套即时测答题记录分析
201   - </p>
  210 + <p class="p1">软件下载</p>
  211 + <p class="p2">授课端软件最新版本1.2.0。</p>
202 212 </div>
203   - <div class="nav-item item1 item-child1" @click="links('/down')">
204   - <img class="icon" src="../../assets/nav/down.png" alt="" />
205   - <div class="text">
206   - <p class="p1">软件下载</p>
207   - <p class="p2">授课端软件最新版本1.2.0。</p>
208   - </div>
209   - </div>
210   - </li>
211   -
  213 + </div>
  214 + </li>
212 215 </ul>
213 216 <ul class="nav-list" v-if="type == 'ROLE_PINGTAI'">
214   - <li class="nav-item item1" @click="links('/account')">
215   - <img class="icon" src="../../assets/nav/setUpAccount.png" alt="" />
216   - <div class="text">
217   - <p class="p1">账号管理</p>
218   - </div>
219   - </li>
220   - <li class="nav-item item1" @click="links('/device')">
221   - <img class="icon" src="../../assets/nav/device.png" alt="" />
222   - <div class="text">
223   - <p class="p1">设备管理</p>
224   - </div>
225   - </li>
226   - <li class="nav-item item2" @click="links('/clientVersion')">
227   - <img class="icon" src="../../assets/nav/down.png" alt="" />
228   - <div class="text">
229   - <p class="p1">授课端版本管理</p>
230   - </div>
231   - </li>
  217 + <li class="nav-item item1" @click="links('/account')">
  218 + <img class="icon" src="../../assets/nav/setUpAccount.png" alt="" />
  219 + <div class="text">
  220 + <p class="p1">账号管理</p>
  221 + </div>
  222 + </li>
  223 + <li class="nav-item item1" @click="links('/device')">
  224 + <img class="icon" src="../../assets/nav/device.png" alt="" />
  225 + <div class="text">
  226 + <p class="p1">设备管理</p>
  227 + </div>
  228 + </li>
  229 + <li class="nav-item item2" @click="links('/clientVersion')">
  230 + <img class="icon" src="../../assets/nav/down.png" alt="" />
  231 + <div class="text">
  232 + <p class="p1">授课端版本管理</p>
  233 + </div>
  234 + </li>
232 235 </ul>
233 236 </div>
234 237 </template>
... ... @@ -241,12 +244,12 @@ export default {
241 244 type: "",
242 245 navList: [],
243 246 dataInfo: {},
244   - code:""
  247 + code: "",
245 248 };
246 249 },
247 250 watch: {
248 251 "$store.getters.info.showRoleName": function (val) {
249   - this._Init(val)
  252 + this._Init(val);
250 253 this._QueryData();
251 254 },
252 255 },
... ... @@ -265,7 +268,9 @@ export default {
265 268 });
266 269 },
267 270 _Init(val) {
268   - this.type = this.$store.getters.info.showRole || this.$store.getters.info.permissions[0].role;
  271 + this.type =
  272 + this.$store.getters.info.showRole ||
  273 + this.$store.getters.info.permissions[0].role;
269 274 this.navList = this.$store.getters.addRouters.map((item) => {
270 275 return {
271 276 name: item.name,
... ... @@ -318,7 +323,7 @@ export default {
318 323 this.$message.error(info);
319 324 }
320 325 },
321   - async personalIndex() {
  326 + async personalIndex() {
322 327 const { data, status, info } = await this.$request.personalIndex();
323 328 if (status === 0) {
324 329 this.dataInfo = { ...data };
... ... @@ -404,7 +409,7 @@ export default {
404 409 height: calc(50% - 8px);
405 410 flex-wrap: wrap;
406 411 padding: 12px 0 12px 30px;
407   - margin-right:20px;
  412 + margin-right: 20px;
408 413 .icon {
409 414 width: 60px;
410 415 height: 60px;
... ... @@ -466,7 +471,6 @@ export default {
466 471 height: 240px;
467 472 display: flex;
468 473 flex-wrap: wrap;
469   -
470 474 }
471 475 .item4 {
472 476 width: calc(50% - 10px);
... ...
src/views/standard/card/index.vue
... ... @@ -8,7 +8,7 @@
8 8  
9 9 <div class="page-content">
10 10 <div class="answer-header">
11   - <div class="sel-box">
  11 + <div class="sel-box" v-if="role == 'ROLE_XUEXIAO'">
12 12 <el-cascader
13 13 @change="_QueryData(1)"
14 14 size="small"
... ... @@ -48,6 +48,22 @@
48 48 >筛选</el-button
49 49 >
50 50 </div>
  51 + <div class="sel-box" v-if="role == 'ROLE_JITUAN'">
  52 + <el-select
  53 + class="sel2"
  54 + v-model="schoolId"
  55 + placeholder="选择学校"
  56 + @change="_QueryData(true)"
  57 + >
  58 + <el-option
  59 + v-for="item in schoolList"
  60 + :key="item.value"
  61 + :label="item.label"
  62 + :value="item.value"
  63 + >
  64 + </el-option>
  65 + </el-select>
  66 + </div>
51 67 </div>
52 68 <el-empty
53 69 :image-size="100"
... ... @@ -113,14 +129,26 @@
113 129 </el-pagination>
114 130 </div>
115 131 </div>
  132 + <p class="down" v-if="tableData.length">
  133 + <el-button
  134 + type="primary"
  135 + plain
  136 + round
  137 + icon="fa fa-cloud-download"
  138 + @click="downExl"
  139 + >导出报表</el-button
  140 + >
  141 + </p>
116 142 </div>
117 143 </div>
118 144 </template>
119 145  
120 146 <script>
  147 +import { downloadFile } from "utils";
121 148 export default {
122 149 data() {
123 150 return {
  151 + role: "",
124 152 loading: false,
125 153 props: { multiple: false },
126 154 query: {
... ... @@ -128,6 +156,8 @@ export default {
128 156 studentName: "",
129 157 studentCode: "",
130 158 },
  159 + schoolId: "",
  160 + schoolList: [],
131 161 gradeList: [],
132 162 tableData: [],
133 163 page: 1,
... ... @@ -135,8 +165,17 @@ export default {
135 165 total: 0,
136 166 };
137 167 },
138   - created() {
139   - this._QueryGradeList();
  168 + async created() {
  169 + this.role =
  170 + this.$store.getters.info.showRole ||
  171 + this.$store.getters.info.permissions[0].role;
  172 + this.loading = true;
  173 + if (this.role == "ROLE_XUEXIAO") {
  174 + this._QueryGradeList();
  175 + } else if (this.role == "ROLE_JITUAN") {
  176 + await this._QuerySchool();
  177 + }
  178 +
140 179 this._QueryData();
141 180 },
142 181 methods: {
... ... @@ -171,23 +210,42 @@ export default {
171 210 this.page = page;
172 211 this._QueryData(4);
173 212 },
  213 + async _QuerySchool() {
  214 + const { data, status, info } = await this.$request.schoolList();
  215 + if (status === 0) {
  216 + this.schoolList =
  217 + data.list?.map((item) => {
  218 + return {
  219 + label: item.schoolName,
  220 + value: item.id,
  221 + };
  222 + }) || [];
  223 + this.schoolId = (this.schoolList && this.schoolList[0].value) || "";
  224 + } else {
  225 + this.$message.error(info);
  226 + }
  227 + },
174 228 async _QueryData(type) {
175 229 let query = {};
176   - query.gradeName = this.query.gradeName;
177   - if (type == 1) {
178   - query.classId = this.query.classId[1] ? this.query.classId[1] : "";
179   - this.query.studentCode = "";
180   - this.query.studentName = "";
181   - } else if (type == 2) {
182   - query.studentName = this.query.studentName;
183   - this.query.classId = "";
184   - this.query.studentCode = "";
185   - } else if (type == 3) {
186   - query.studentCode = this.query.studentCode;
187   - this.query.classId = "";
188   - this.query.studentName = "";
189   - } else {
190   - query = { ...this.query };
  230 + if (this.role == "ROLE_XUEXIAO") {
  231 + query.gradeName = this.query.gradeName;
  232 + if (type == 1) {
  233 + query.classId = this.query.classId[1] ? this.query.classId[1] : "";
  234 + this.query.studentCode = "";
  235 + this.query.studentName = "";
  236 + } else if (type == 2) {
  237 + query.studentName = this.query.studentName;
  238 + this.query.classId = "";
  239 + this.query.studentCode = "";
  240 + } else if (type == 3) {
  241 + query.studentCode = this.query.studentCode;
  242 + this.query.classId = "";
  243 + this.query.studentName = "";
  244 + } else {
  245 + query = { ...this.query };
  246 + }
  247 + } else if (this.role == "ROLE_JITUAN") {
  248 + query.schoolId = this.schoolId;
191 249 }
192 250 this.loading = true;
193 251 const { data, status, info } = await this.$request.cardList({
... ... @@ -204,6 +262,28 @@ export default {
204 262 this.$message.error(info);
205 263 }
206 264 },
  265 + async downExl() {
  266 + //报表导出
  267 + if (this.exportLoading == true) return;
  268 + let query = {};
  269 + if (this.role == "ROLE_XUEXIAO") {
  270 + query = { ...this.query };
  271 + } else if (this.role == "ROLE_JITUAN") {
  272 + query.schoolId = this.schoolId;
  273 + }
  274 +
  275 + this.exportLoading = true;
  276 + const data = await this.$request.exportClickersLog({ ...query });
  277 + this.exportLoading = false;
  278 + if (data) {
  279 + let blob = new Blob([data], {
  280 + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  281 + });
  282 + downloadFile("发卡记录.xlsx", blob);
  283 + } else {
  284 + this.$message.error("下载失败");
  285 + }
  286 + },
207 287 },
208 288 };
209 289 </script>
... ... @@ -212,4 +292,10 @@ export default {
212 292 .table-box {
213 293 padding: 0 20px;
214 294 }
  295 +.down {
  296 + padding: 16px 20px;
  297 +}
  298 +.answer-header .sel-box .sel2 {
  299 + width: 300px;
  300 +}
215 301 </style>
216 302 \ No newline at end of file
... ...
src/views/standard/setUp/teacher.vue
... ... @@ -773,15 +773,13 @@ export default {
773 773 },
774 774 async downExcel() {
775 775 let { data, status, info } = await this.$request.teacherTemplate();
776   - debugger;
777   - if (status == 0) {
778   - const a = document.createElement("a");
779   - a.href = data.downloadUrl;
780   - document.body.appendChild(a);
781   - a.click();
782   - a.remove();
  776 + if (data && !data.code) {
  777 + let blob = new Blob([data], {
  778 + type: "application/vnd.ms-excel;charset=utf-8",
  779 + });
  780 + downloadFile(`教师名单模版.xlsx`, blob);
783 781 } else {
784   - this.$message.error(info);
  782 + this.$message.error(data.info);
785 783 }
786 784 },
787 785 async exportTeacherExl() {
... ... @@ -814,6 +812,13 @@ export default {
814 812 .teacher-ul {
815 813 max-height: 60vh;
816 814 overflow-y: scroll;
  815 + &::-webkit-scrollbar {
  816 + width: 6px;
  817 + }
  818 + &::-webkit-scrollbar-thumb {
  819 + border-radius: 10px;
  820 + background-color: #ccc;
  821 + }
817 822 }
818 823 .teacher-list {
819 824 width: 240px;
... ... @@ -822,7 +827,7 @@ export default {
822 827 height: 40px;
823 828 line-height: 40px;
824 829 background: #eee;
825   - border-radius: 10px 10px 0 0;
  830 + // border-radius: 10px 10px 0 0;
826 831 }
827 832 .teacher-item {
828 833 font-size: 16px;
... ... @@ -843,6 +848,7 @@ export default {
843 848 .teacher-detail {
844 849 flex: 1;
845 850 position: relative;
  851 + padding-left: 10px;
846 852 .icon-box {
847 853 position: absolute;
848 854 top: 12px;
... ...
src/views/standard/test/index.vue
... ... @@ -572,6 +572,7 @@ export default {
572 572 });
573 573 },
574 574 toPortrait(obj) {
  575 + //暂时不上线
575 576 return
576 577 if (this.$store.getters.code) {
577 578 return;
... ...