get.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. <template>
  2. <div class="sz_body" v-loading="loading">
  3. <div @click="exportExcel" v-show="false">导出</div>
  4. <div style="font-size: 18px;margin-bottom: 20px;">评分人数:<span class="color">{{ num }}</span>人 总平均分:<span
  5. class="color">{{ num ? score ? (score / num).toFixed(1) : 0 : 0 }}</span></div>
  6. <div class="test_box" v-for="(item, index) in testList" :key="index">
  7. <div class="testTitle">{{ item.title }}</div>
  8. <div class="testContent" v-if="item.type == '1'" v-for="(item2, index2) in item.array"
  9. :key="index + '-' + index2">
  10. <div class="testContent_title">{{ index2 + 1 }}、{{ item2.title }}</div>
  11. <div class="testContent_input">
  12. <!-- <el-input v-model="item2.uscore" class="c_input" @change="numberPan(index, index2, item2.score)"
  13. placeholder="请输入评分" /> -->
  14. <span>平均分:</span>
  15. <span class="color">{{ num ? item2.uscore ? (item2.uscore / num).toFixed(2) : 0 : 0 }}</span>
  16. </div>
  17. </div>
  18. <div v-if="item.type == '2'">
  19. <div class="test_ping" v-for="(answer, index2) in item.answerArray" :key="index + '-' + index2">
  20. <span style=" min-width: fit-content;">{{ index2 + 1 }}.</span>
  21. <span>{{ answer }}</span>
  22. </div>
  23. </div>
  24. </div>
  25. </div>
  26. </template>
  27. <script>
  28. export default {
  29. props: {
  30. courseid: {
  31. type: String,
  32. default: ''
  33. },
  34. title: {
  35. type: String,
  36. default: ''
  37. },
  38. },
  39. data() {
  40. return {
  41. userid:"",
  42. testList: [
  43. {
  44. title: '教学目标(5分)',
  45. type: '1',
  46. array: [
  47. {
  48. title: '目标结构完整,能够清晰地表达学生的学习过程与预期成果。目标符合学情,具有可行性与逻辑递进性。目标体现学生本位与素养导向,不单纯停留在知识与技能层面。',
  49. score: 5,
  50. uscore: 0,
  51. }
  52. ],
  53. },
  54. {
  55. title: '教学内容(5分)',
  56. type: '1',
  57. array: [
  58. {
  59. title: '重难点突出,符合课标与教材要求,不超纲。符合学情特点,贴近学生生活,体现积极向上的育人价值观。关注学生学习的最近发展区,有意识地展现因材施教的意图。',
  60. score: 5,
  61. uscore: 0,
  62. }
  63. ],
  64. },
  65. {
  66. title: '教学过程(30分)',
  67. type: '1',
  68. array: [
  69. {
  70. title: '课堂结构合理、紧密,层次清楚,突出重难点的解决。(10分)',
  71. score: 10,
  72. uscore: 0,
  73. },
  74. {
  75. title: '强调“学”的活动设计,教与学有机结合。(10分)',
  76. score: 10,
  77. uscore: 0,
  78. },
  79. {
  80. title: '课堂管理有序,教学语言清晰准确,能及时、合理地解决课堂问题,体现良好的教学素养。(10分)',
  81. score: 10,
  82. uscore: 0,
  83. }
  84. ],
  85. },
  86. {
  87. title: '教学方法与策略(20分)',
  88. type: '1',
  89. array: [
  90. {
  91. title: '符合教学内容与学科特点。落实有效,能体现出学生的学习成效,不流于形式。具有一定的新意,展现教师的独立思考与探究意识。',
  92. score: 20,
  93. uscore: 0,
  94. }
  95. ],
  96. },
  97. {
  98. title: '教学工具(15分)',
  99. type: '1',
  100. array: [
  101. {
  102. title: '合理、科学地使用信息化技术、学习单、自制教学道具、辅助性资源等教学工具。',
  103. score: 15,
  104. uscore: 0,
  105. }
  106. ],
  107. },
  108. {
  109. title: '教学评价(10分)',
  110. type: '1',
  111. array: [
  112. {
  113. title: '重视评价,有合理的评价手段与工具。评价落实有效,体现针对性和专业性。',
  114. score: 10,
  115. uscore: 0,
  116. }
  117. ],
  118. },
  119. {
  120. title: '创新意识(10分)',
  121. type: '1',
  122. array: [
  123. {
  124. title: '教学空间的选择、布置有独特想法,且合理有效。敢于尝试多样化的教学形式,如主题式、大单元、项目式、游戏化等。开发特色有效的教学策略与手段,如小组合作探究、跨学科展演等,教师特色鲜明。',
  125. score: 10,
  126. uscore: 0,
  127. }
  128. ],
  129. },
  130. {
  131. title: '教学效果(5分)',
  132. type: '1',
  133. array: [
  134. {
  135. title: '达成目标,整个过程有资源的生成。学习过程中学生有满足、成功与喜悦等体验,对后续学习更有信心,能力得到发展。',
  136. score: 5,
  137. uscore: 0,
  138. }
  139. ],
  140. },
  141. {
  142. title: '加分项(10分)',
  143. type: '1',
  144. array: [
  145. {
  146. title: '某项优点特别突出,如教学风貌、教学理念、教学特色、教学手段等。',
  147. score: 10,
  148. uscore: 0,
  149. }
  150. ],
  151. },
  152. {
  153. title: '评语',
  154. type: '2',
  155. answer: '',
  156. answerArray: [],
  157. },
  158. ],
  159. num: 0,
  160. score: 0,
  161. loading: false,
  162. testArray: []
  163. }
  164. },
  165. mounted() {
  166. this.getList();
  167. },
  168. methods: {
  169. exportExcel() {
  170. try {
  171. var res = this.testArray;
  172. //如果value的json字段的key值和想要的headers值不一致时,可做如下更改
  173. //将和下面的Object.fromEntries结合,将json字段的key值改变为要求的excel的header值
  174. var array = [];
  175. for (var i = 0; i < res.length; i++) {
  176. var _json = {};
  177. _json["序号"] = i+1;
  178. _json["姓名"] = res[i].username;
  179. _json["教学目标(5分)"] = res[i]['test00'];
  180. _json["教学内容(5分)"] = res[i]['test10'];
  181. _json["教学过程-1课程结构(10分)"] = res[i]['test20'];
  182. _json["教学过程-2活动设计(10分)"] = res[i]['test21'];
  183. _json["教学过程-3秩序管理(10分)"] = res[i]['test22'];
  184. _json["教学方法与策略(20分)"] = res[i]['test30'];
  185. _json["教学工具(15分)"] = res[i]['test40'];
  186. _json["教学评价(10分)"] = res[i]['test50'];
  187. _json["创新意识(10分)"] = res[i]['test60'];
  188. _json["教学效果(5分)"] = res[i]['test70'];
  189. _json["加分项(10分)"] = res[i]['test80'];
  190. _json["总分(110分)"] = res[i]['sum'];
  191. _json["评语"] = res[i]['ping'];
  192. array.push(_json);
  193. }
  194. var XLSX = require("xlsx");
  195. const workbook = XLSX.utils.book_new(); //创建一个新的工作簿对象
  196. let ws = XLSX.utils.json_to_sheet(array); //将json对象数组转化成工作表
  197. // ws["!cols"] = [
  198. // //设置每一列的宽度
  199. // { wch: 50 },
  200. // { wch: 50 },
  201. // { wch: 50 },
  202. // ];
  203. XLSX.utils.book_append_sheet(workbook, ws, "sheet1"); //把sheet添加到workbook里,第三个参数是sheet名
  204. XLSX.writeFile(workbook, this.title+".xlsx");
  205. // const wopts = { bookType: "xlsx", bookSST: false, type: "array" };//写入的样式bookType:输出的文件类型,type:输出的数据类型,bookSST: 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
  206. // const wbout = XLSX.write(workbook, wopts);// 浏览器端和node共有的API,实际上node可以直接使用xlsx.writeFile来写入文件,但是浏览器没有该API
  207. // FileSaver.saveAs(new Blob([wbout], { type: "application/octet-stream" }), `${title} demo.xlsx`);//保存文件
  208. this.$message({
  209. message: "导出成功",
  210. type: "success",
  211. });
  212. } catch (e) {
  213. console.log(e, e.stack);
  214. }
  215. },
  216. numberPan(index, index2, score) {
  217. let _score = this.testList[index].array[index2].uscore
  218. if (/[^\d]/.test(_score) || _score < 0) {
  219. this.$message.error('请输入大于0的整数')
  220. this.testList[index].array[index2].uscore = 0
  221. }
  222. if (parseInt(_score) > parseInt(score)) {
  223. this.$message.error('不能输入大于得分的整数')
  224. this.testList[index].array[index2].uscore = score
  225. }
  226. this.$forceUpdate();
  227. },
  228. confirm() {
  229. let params = [
  230. {
  231. cid: this.courseid,
  232. uid: this.userid,
  233. json: JSON.stringify(this.testList),
  234. },
  235. ];
  236. this.ajax
  237. .post(this.$store.state.api + "opCourseScore", params)
  238. .then((res) => {
  239. console.log(res.data);
  240. this.$message({
  241. message: "添加成功",
  242. type: "success",
  243. });
  244. this.getList();
  245. this.$forceUpdate();
  246. })
  247. .catch((err) => {
  248. console.error(err);
  249. });
  250. },
  251. getList() {
  252. let params =
  253. {
  254. cid: this.courseid,
  255. };
  256. this.loading = true
  257. this.ajax
  258. .get(this.$store.state.api + "getCourseScore", params)
  259. .then((res) => {
  260. console.log(res.data);
  261. if (res.data[0].length > 0) {
  262. // this.testList = JSON.parse(res.data[0][0].json)
  263. let data = res.data[0]
  264. this.num = data.length
  265. let sum = 0
  266. for (var i = 0; i < data.length; i++) {
  267. let item = data[i]
  268. let _json = JSON.parse(item.json)
  269. for (var j = 0; j < this.testList.length; j++) {
  270. let test = this.testList[j]
  271. if (test.type == '2') {
  272. if (_json[j].answer) {
  273. test.answerArray.push(_json[j].answer)
  274. }
  275. } else {
  276. for (var k = 0; k < test.array.length; k++) {
  277. let _item = test.array[k]
  278. _item.uscore += _item.score / 5 * parseInt(_json[j].array[k].uscore)
  279. _item.num++
  280. sum += _item.score / 5 * parseInt(_json[j].array[k].uscore)
  281. }
  282. }
  283. }
  284. }
  285. this.score = sum
  286. let testArray = []
  287. for (var i = 0; i < data.length; i++) {
  288. let item = data[i]
  289. let _json = JSON.parse(item.json)
  290. let _sum = 0
  291. for (var j = 0; j < this.testList.length; j++) {
  292. let test = this.testList[j]
  293. if (test.type == '2') {
  294. if (_json[j].answer) {
  295. item['ping'] = _json[j].answer
  296. }else {
  297. item['ping'] = ''
  298. }
  299. } else {
  300. for (var k = 0; k < test.array.length; k++) {
  301. let _item = test.array[k]
  302. item['test'+j+k] = _item.score / 5 * parseInt(_json[j].array[k].uscore)
  303. _sum += _item.score / 5 * parseInt(_json[j].array[k].uscore)
  304. }
  305. }
  306. }
  307. item['sum'] = _sum
  308. testArray.push(item)
  309. }
  310. this.testArray = testArray
  311. }
  312. this.loading = false
  313. this.$forceUpdate();
  314. })
  315. .catch((err) => {
  316. this.loading = false
  317. console.error(err);
  318. });
  319. }
  320. },
  321. }
  322. </script>
  323. <style scoped>
  324. .sz_body {
  325. width: 100%;
  326. height: 100%;
  327. overflow: auto;
  328. }
  329. .test_box {
  330. margin-bottom: 20px;
  331. }
  332. .testTitle {
  333. font-size: 16px;
  334. font-weight: 600;
  335. }
  336. .testContent {}
  337. .testContent_title {
  338. margin-top: 10px;
  339. }
  340. .testContent_input {
  341. margin-top: 5px;
  342. }
  343. .test_ping {
  344. margin-top: 5px;
  345. display: flex;
  346. word-break: break-all;
  347. }
  348. .color {
  349. color: #3681fc;
  350. }
  351. </style>