Browse Source

10.14

master
lichong 6 months ago
parent
commit
13c4a21593
  1. BIN
      dataDeal/一年级.xlsx
  2. BIN
      dataDeal/七年级.xlsx
  3. BIN
      dataDeal/三年级.xlsx
  4. BIN
      dataDeal/九年级.xlsx
  5. BIN
      dataDeal/二年级.xlsx
  6. BIN
      dataDeal/五年级.xlsx
  7. 1
      front/package.json
  8. 2
      front/src/renderer/index.html
  9. 7
      front/src/renderer/src/assets/json/student.json
  10. 150
      front/src/renderer/src/components/tablecomponent.vue
  11. 9
      front/src/renderer/src/main.js
  12. 97
      front/src/renderer/src/views/student.vue

BIN
dataDeal/一年级.xlsx

Binary file not shown.

BIN
dataDeal/七年级.xlsx

Binary file not shown.

BIN
dataDeal/三年级.xlsx

Binary file not shown.

BIN
dataDeal/九年级.xlsx

Binary file not shown.

BIN
dataDeal/二年级.xlsx

Binary file not shown.

BIN
dataDeal/五年级.xlsx

Binary file not shown.

1
front/package.json

@ -23,6 +23,7 @@
"lodash": "^4.17.21",
"node-machine-id": "^1.1.12",
"vue-web-screen-shot": "^1.5.3",
"vxe-table": "^4.7.87",
"xlsx": "^0.18.5"
},
"devDependencies": {

2
front/src/renderer/index.html

@ -7,7 +7,7 @@
<!-- <link rel="icon" href="/icon/icon.jpg" /> -->
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self';img-src 'self' data:; style-src 'self' 'unsafe-inline'" />
content="default-src 'self'; script-src 'self';img-src 'self' data:; style-src 'self' 'unsafe-inline';font-src 'self' data:;" />
</head>
<body>

7
front/src/renderer/src/assets/json/student.json

@ -10,6 +10,7 @@
"sort": "",
"isSort": true,
"isSearch": true,
"searchType": "select",
"openPopoverVisible": false,
"searchValue": "",
"formShow": true,
@ -26,6 +27,7 @@
"sort": "",
"isSort": true,
"isSearch": true,
"searchType": "select",
"openPopoverVisible": false,
"searchValue": "",
"formShow": false,
@ -489,8 +491,8 @@
"prop": "totalScore",
"type": "number",
"index": "33",
"fixed": false,
"tableShow": true,
"fixed": "right",
"setTableShow": true,
"sort": "",
"formShow": false,
@ -501,11 +503,12 @@
"prop": "level",
"type": "text",
"index": "34",
"fixed": false,
"tableShow": true,
"fixed": "right",
"setTableShow": true,
"sort": "",
"isSearch": true,
"searchType": "select",
"openPopoverVisible": false,
"searchValue": "",
"formShow": false,

150
front/src/renderer/src/components/tablecomponent.vue

@ -1,117 +1,52 @@
<template>
<div class="tableClass">
<el-table :data="tableData" height="calc(100vh - 355px)" border @select="selectChange" @select-all="selectChange"
fit :row-key="getRowKeys" ref="tableRef">
<el-table-column type="selection" width="50" :reserve-selection="true" fixed="left">
</el-table-column>
<el-table-column type="index" v-if="hiddenXuhao" width="60" :reserve-selection="true" fixed="left" label="序号">
<template #default="scope">
<span>{{ pageSize * (currentPage - 1) + scope.$index + 1 }}</span>
<vxe-table show-overflow :data="tableData" round :height="690" :scroll-y="{ enabled: true, gt: 20 }"
:checkbox-config="{ labelField: 'seq', highlight: true }" @checkbox-all="selectAllChangeEvent"
@checkbox-change="selectChange" ref="tableRef">
<vxe-column type="seq" width="70" v-if="hiddenXuhao"></vxe-column>
<vxe-column type="checkbox" width="70" fixed="left"></vxe-column>
<vxe-column :field="headerItem.prop" :title="headerItem.label" :min-width="`${headerItem.label.length * 23 + 24}`"
v-for="(headerItem, headerIndex) in tableHeader" :key="headerIndex" :fixed="!!headerItem.fixed ? 'left' : ''"
:sortable="headerItem.isSort">
<template #default="{ row }">
<template v-if="headerItem.type === 'text'">
<span>{{ row[headerItem.prop] }}</span>
</template>
<template v-else-if="headerItem.type === 'select'">
<span>{{ (_.find(headerItem.tableDisplay, { value: `${row[headerItem.prop]}` }) || {}).label }}</span>
</template>
<template v-else-if="headerItem.type === 'date'">
<span>{{ row[headerItem.prop] }}</span>
</template>
<template v-else-if="headerItem.type === 'number'">
<span>{{ row[headerItem.prop] }}</span>
</template>
<template v-else>{{ row[headerItem.prop] }}</template>
</template>
</el-table-column>
<el-table-column v-for="(headerItem, headerIndex) in tableHeader" :label="headerItem.label" show-overflow-tooltip
:key="headerIndex" :min-width="`${headerItem.label.length * 23 + 22}px`" :fixed="!!headerItem.fixed">
<template #header="{ column, $index }">
<div>
<span :style="`${column.label === '得分' ? 'color:#F56C6C' : ''}`">{{ column.label }}</span>
<!-- <span v-if="headerItem.isSearch">
<el-popover :width="350" trigger="click" placement="bottom-start" :hide-after="50"
:visible="headerItem.popoverVisible">
<template #reference>
<span @click="openPopoverVisible(headerItem)">
<el-icon style="position: relative;top: 2px;" v-if="!searchParams[headerItem.prop]">
<Filter />
</el-icon>
<el-icon style="position: relative;top: 2px;" v-else>
<Checked />
</el-icon>
</span>
</template>
<template #default>
<div>
<template v-if="headerItem.type === 'text'">
<el-input v-model="searchParams[headerItem.prop]" style="width: 200px;padding-right: 20px;"
clearable @keyup.enter="searchValue(headerItem)" />
</template>
<template v-if="headerItem.type === 'select'">
<el-select v-model="searchParams[headerItem.prop]" size="large"
style="width: 200px;padding-right: 20px;" clearable @change="searchValue(headerItem)">
<el-option v-for="item in headerItem.tableDisplay" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</template>
<template v-else-if="headerItem.type === 'date'">
<el-date-picker v-model="searchParams[headerItem.prop]" type="date"
:disabled="['create_at', 'update_at'].indexOf(headerItem.prop) !== -1"
:placeholder="`请选择${headerItem.label}`" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
style="width: 200px;padding-right: 20px;" clearable @change="searchValue(headerItem)" />
</template>
<el-button type="primary" @click="searchValue(headerItem)">
<el-icon>
<Search />
</el-icon>
<span>搜索</span>
</el-button>
</div>
</template>
</el-popover>
</span> -->
<span v-if="headerItem.isSort">
<span @click="headerSort(headerItem)">
<el-icon style="position: relative;top: 2px;" v-if="headerItem.sort === ''">
<Sort />
</el-icon>
<el-icon style="position: relative;top: 2px;" v-else-if="headerItem.sort === 1">
<SortUp />
</el-icon>
<el-icon style="position: relative;top: 2px;" v-else-if="headerItem.sort === -1">
<SortDown />
</el-icon>
</span>
</span>
</div>
</template>
<template #default="{ row, column, $index }">
<div :style="`${column.label === '得分' ? 'color:#F56C6C' : ''}`">
<template v-if="headerItem.type === 'text'">
<span>{{ row[headerItem.prop] }}</span>
</template>
<template v-else-if="headerItem.type === 'select'">
<span>{{ (_.find(headerItem.tableDisplay, { value: `${row[headerItem.prop]}` }) || {}).label }}</span>
</template>
<template v-else-if="headerItem.type === 'date'">
<span>{{ row[headerItem.prop] }}</span>
</template>
<template v-else-if="headerItem.type === 'number'">
<span>{{ row[headerItem.prop] }}</span>
</template>
<template v-else>{{ row[headerItem.prop] }}</template>
</div>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" width="145">
<template #default="scope">
<el-button type="primary" circle @click="optClick(scope.row, 'edit')">
</vxe-column>
<vxe-column fixed="right" title="操作" width="145">
<template #default="{ row }">
<el-button type="primary" circle @click="optClick(row, 'edit')">
<el-icon>
<Edit />
</el-icon>
</el-button>
<!-- <el-button type="info" circle @click="optClick(scope.row, 'info')">
<!-- <el-button type="info" circle @click="optClick(row, 'info')">
<el-icon>
<InfoFilled />
</el-icon>
</el-button> -->
<el-button type="danger" circle @click="optClick(scope.row, 'del')">
<el-button type="danger" circle @click="optClick(row, 'del')">
<el-icon>
<Delete />
</el-icon>
</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination style="margin:8px 0 0 0;place-content:center;" v-model:current-page="currentPage"
</vxe-column>
</vxe-table>
<!-- <el-pagination style="margin:8px 0 0 0;place-content:center;" v-model:current-page="currentPage"
v-model:page-size="pageSize" :total="total" layout="total, sizes, prev, pager, next, jumper"
:page-sizes="pageSizes"></el-pagination>
:page-sizes="pageSizes"></el-pagination> -->
</div>
</template>
@ -171,8 +106,19 @@ export default {
}
},
methods: {
selectChange(selection) {
this.$emit("selectChange", selection)
selectChange({ checked }) {
let $table = this.$refs.tableRef
if ($table) {
let selection = $table.getCheckboxRecords()
this.$emit("selectChange", selection)
}
},
selectAllChangeEvent({ checked }) {
let $table = this.$refs.tableRef
if ($table) {
let selection = $table.getCheckboxRecords()
this.$emit("selectChange", selection)
}
},
handleSizeChange(pageSize) {
this.$emit("handleSizeChange", pageSize)
@ -188,7 +134,10 @@ export default {
return row.id; //
},
clearSelection() {
this.$refs.tableRef.clearSelection()
const $table = this.$refs.tableRef
if ($table) {
$table.clearCheckboxRow()
}
},
searchValue(item) {
item.popoverVisible = false
@ -241,6 +190,7 @@ export default {
</script>
<style scoped>
.tableClass {
height: calc(100vh - 325px);
text-align: center;
text-align-last: center;
}

9
front/src/renderer/src/main.js

@ -6,6 +6,13 @@ import 'element-plus/dist/index.css'
import App from './App.vue'
import './assets/css/base.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import VxeUI from 'vxe-pc-ui'
import 'vxe-pc-ui/lib/style.css'
// ...
// 完整导入 表格库
import VxeUITable from 'vxe-table'
import 'vxe-table/lib/style.css'
import screenShort from "vue-web-screen-shot";
const app = createApp(App)
@ -16,7 +23,7 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.use(ElementPlus, {
locale: zhCn,
})
app.use(screenShort, { enableWebRtc: false,level:300001,hiddenScrollBar:true })
app.use(screenShort, { enableWebRtc: false, level: 300001, hiddenScrollBar: true }).use(VxeUI).use(VxeUITable)
app.mount('#app')
document.addEventListener('keydown', (event) => {

97
front/src/renderer/src/views/student.vue

@ -3,14 +3,22 @@
<div>
<el-row>
<el-col v-for="(headerItem, headerIndex) in _.filter(tableHeader, item => item.isSearch)" :key="headerIndex"
:span="4">
:span="headerItem.searchType === 'select' ? 5 : 4">
<div>
<span>{{ headerItem.label }}:</span>
<template v-if="headerItem.type === 'text'">
<template v-if="headerItem.searchType === 'select'">
<el-select v-model="searchParams[headerItem.prop]" size="large" multiple
style="width: 150px;padding-right: 8px;margin:8px 0" clearable collapse-tags collapse-tags-tooltip
:max-collapse-tags="1" @change="searchData()">
<el-option v-for="item in headerItem.options" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</template>
<template v-else-if="headerItem.type === 'text'">
<el-input v-model="searchParams[headerItem.prop]" style="width: 150px;padding-right: 8px;margin:8px 0"
clearable @keyup.enter="searchData()" />
</template>
<template v-if="headerItem.type === 'select'">
<template v-else-if="headerItem.type === 'select'">
<el-select v-model="searchParams[headerItem.prop]" size="large"
style="width: 150px;padding-right: 8px;margin:8px 0" clearable @change="searchData()">
<el-option v-for="item in headerItem.tableDisplay" :key="item.value" :label="item.label"
@ -25,7 +33,7 @@
</template>
</div>
</el-col>
<el-col :span="6">
<el-col :span="3">
<el-button type="primary" @click="searchData()" size="large">
<el-icon>
<Search />
@ -34,7 +42,6 @@
</el-button>
</el-col>
</el-row>
<el-button type="primary" @click="addData">
<el-icon>
<Plus />
@ -118,7 +125,9 @@
</span>
<span>
<el-tag size="small" style="position: relative;top: -1px;">
{{ Number(((_.filter(allData, { level: "优秀" })) / (allData.length || 1)).toFixed(2)) * 100 }}%
{{
parseInt(Number(((_.filter(allData, { level: "优秀" }).length) / (allData.length || 1)).toFixed(2)) * 100)
}}%
</el-tag>
</span>
</el-descriptions-item>
@ -128,7 +137,9 @@
</span>
<span>
<el-tag size="small" style="position: relative;top: -1px;">
{{ Number(((_.filter(allData, { level: "良好" })).length / (allData.length || 1)).toFixed(2)) * 100 }}%
{{
parseInt(Number(((_.filter(allData, { level: "良好" })).length / (allData.length || 1)).toFixed(2)) * 100)
}}%
</el-tag>
</span>
</el-descriptions-item>
@ -138,7 +149,9 @@
</span>
<span>
<el-tag size="small" style="position: relative;top: -1px;">
{{ Number(((_.filter(allData, { level: "及格" })).length / (allData.length || 1)).toFixed(2)) * 100 }}%
{{
parseInt(Number(((_.filter(allData, { level: "及格" })).length / (allData.length || 1)).toFixed(2)) * 100)
}}%
</el-tag>
</span>
</el-descriptions-item>
@ -148,13 +161,15 @@
</span>
<span>
<el-tag size="small" style="position: relative;top: -1px;">
{{ Number(((_.filter(allData, { level: "不及格" })).length / (allData.length || 1)).toFixed(2)) * 100 }}%
{{
parseInt(Number(((_.filter(allData, { level: "不及格" })).length / (allData.length || 1)).toFixed(2)) * 100)
}}%
</el-tag>
</span>
</el-descriptions-item>
</el-descriptions>
</div>
<div>
<div v-loading="loading">
<tablecomponent :tableHeader="tableHeader" :tableData="tableData" :searchParams="searchParams"
:pageSizes="pageSizes" :total="total" @selectChange="selectChange" @handleCurrentChange="handleCurrentChange"
@handleSizeChange="handleSizeChange" @edit="edit" @info="info" @del="del" @searchValue="searchData"
@ -227,6 +242,7 @@ export default {
},
setHeaderVisible: false,
sortObj: {},
loading: false,
}
},
methods: {
@ -277,8 +293,8 @@ export default {
type: 'error',
})
}
await that.searchData()
}
await that.searchData(true)
}
fileReader.onerror = function (error) {
ElMessage({
@ -398,25 +414,36 @@ export default {
},
//
async updateSeach(params = {}) {
async updateSeach(params = {}, isAll = false) {
this.loading = true
let allStudentList = _.cloneDeep(await myDatabase.student.toArray())
if (!_.isEmpty(params)) {
let paramsTemp = {}
for (let key in params) {
let value = params[key]
if (["undefined", "", "null"].indexOf(`${value}`) === -1) {
paramsTemp[key] = [`${value}`, Number(value)]
if (value.indexOf(",")) {
paramsTemp[key] = [..._.split(value, ","), ..._.split(value, ",").map(item => Number(item))]
} else {
paramsTemp[key] = [`${value}`, Number(value)]
}
}
}
let dataTemp = []
if (!_.isEmpty(paramsTemp)) {
for (let i = 0; i < allStudentList.length; i++) {
let element = allStudentList[i];
let istrue = true
for (let key in paramsTemp) {
if (paramsTemp[key].includes(element[key])) {
dataTemp.push({ ...element })
} else {
istrue = false
}
}
if (istrue) {
dataTemp.push({ ...element })
}
}
allStudentList = _.cloneDeep(dataTemp)
}
@ -425,13 +452,43 @@ export default {
//
allStudentList = _.cloneDeep(_.orderBy(allStudentList, [this.sortObj.prop], [_.get(this.sortObj, ["sort"], "") === 1 ? 'desc' : 'asc']))
}
this.allData = _.cloneDeep(allStudentList)
this.total = allStudentList.length
this.tableData = allStudentList.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize)
let allData = _.uniqBy(allStudentList, "id")
this.allData = _.cloneDeep(allData)
this.total = allData.length
this.tableData = allData
if (isAll) {
let groupObj = {
nianjicodeGroupyData: _.groupBy(allStudentList, "nianjicode"),
banjicodeGroupyData: _.groupBy(allStudentList, "banjicode"),
levelGroupyData: _.groupBy(allStudentList, "level"),
}
for (let key in groupObj) {
let value = groupObj[key]
let findIndex = _.findIndex(this.tableHeader, { prop: `${key.slice(0, key.length - 10)}` })
let headerItem = this.tableHeader[findIndex]
let keys = _.keys(value)
let options = []
for (let j = 0; j < keys.length; j++) {
let element = keys[j];
if ((!_.find(options, { label: element })) && element) {
options.push(
{
label: `${element}`,
value: `${element}`
}
)
}
}
headerItem["options"] = options
}
}
this.loading = false
// this.tableData = allStudentList.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize)
},
//
async searchData() {
await this.updateSeach(this.searchParams)
async searchData(isAll = false) {
await this.updateSeach(this.searchParams, isAll)
},
//
async headerSort(headerSort) {
@ -671,7 +728,7 @@ export default {
this.tableHeader = _.filter(this.setTableHeader, o => o.setTableShow)
this.formHeader = _.filter(tableHeaderLocal, o => o.formShow)
this.exportHeader = _.filter(tableHeaderLocal, o => o.export)
await this.updateSeach()
await this.updateSeach({}, true)
this.$watch("setTableHeader", (val) => {
this.tableHeader = _.filter(val, o => o.setTableShow)
localStorage.setItem('setTableHeader', JSON.stringify(val))

Loading…
Cancel
Save