'新增页面'

This commit is contained in:
esacpe
2025-09-22 14:21:17 +08:00
parent 21e2a12e3c
commit 7e300cbc30
19 changed files with 905 additions and 61 deletions

134
package-lock.json generated
View File

@ -1162,9 +1162,9 @@
} }
}, },
"@ctrl/tinycolor": { "@ctrl/tinycolor": {
"version": "3.4.1", "version": "3.6.1",
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz", "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
"integrity": "sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw==" "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA=="
}, },
"@element-plus/icons": { "@element-plus/icons": {
"version": "0.0.11", "version": "0.0.11",
@ -1173,9 +1173,31 @@
"dev": true "dev": true
}, },
"@element-plus/icons-vue": { "@element-plus/icons-vue": {
"version": "0.2.7", "version": "2.3.2",
"resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-0.2.7.tgz", "resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.2.tgz",
"integrity": "sha512-S8kDbfVaWkQvbUYQE1ui448tzaHfUvyESCep9J6uPRlViyQPXjdIfwLBhV6AmQSOfFS8rL+xehJGhvzPXLrSBg==" "integrity": "sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A=="
},
"@floating-ui/core": {
"version": "1.7.3",
"resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.7.3.tgz",
"integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==",
"requires": {
"@floating-ui/utils": "^0.2.10"
}
},
"@floating-ui/dom": {
"version": "1.7.4",
"resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.7.4.tgz",
"integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==",
"requires": {
"@floating-ui/core": "^1.7.3",
"@floating-ui/utils": "^0.2.10"
}
},
"@floating-ui/utils": {
"version": "0.2.10",
"resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.10.tgz",
"integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="
}, },
"@fullcalendar/common": { "@fullcalendar/common": {
"version": "5.11.2", "version": "5.11.2",
@ -1436,9 +1458,9 @@
"integrity": "sha512-3MUulwMtsdCA9lw8a/Kc0XDBJJVCkYTQ5aGd+///TbfkOMXoOGAzzoiYKwPEsLYZv7He7fKJ/mCacqKOO7REyg==" "integrity": "sha512-3MUulwMtsdCA9lw8a/Kc0XDBJJVCkYTQ5aGd+///TbfkOMXoOGAzzoiYKwPEsLYZv7He7fKJ/mCacqKOO7REyg=="
}, },
"@popperjs/core": { "@popperjs/core": {
"version": "2.11.5", "version": "npm:@sxzz/popperjs-es@2.11.7",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz", "resolved": "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
"integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==" "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ=="
}, },
"@samverschueren/stream-to-observable": { "@samverschueren/stream-to-observable": {
"version": "0.3.1", "version": "0.3.1",
@ -1618,6 +1640,19 @@
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
"dev": true "dev": true
}, },
"@types/lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA=="
},
"@types/lodash-es": {
"version": "4.17.12",
"resolved": "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.12.tgz",
"integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
"requires": {
"@types/lodash": "*"
}
},
"@types/mime": { "@types/mime": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.0.tgz",
@ -1702,6 +1737,11 @@
"resolved": "https://registry.npmjs.org/@types/video.js/-/video.js-7.3.42.tgz", "resolved": "https://registry.npmjs.org/@types/video.js/-/video.js-7.3.42.tgz",
"integrity": "sha512-AD6AQNMgLTqrgoayC6SshKh8EDkDd9x5pmEuiY9YsniHlhn5jPXdkVqrzKLwviapaRhQF15TQYxo1JWpqXCUBg==" "integrity": "sha512-AD6AQNMgLTqrgoayC6SshKh8EDkDd9x5pmEuiY9YsniHlhn5jPXdkVqrzKLwviapaRhQF15TQYxo1JWpqXCUBg=="
}, },
"@types/web-bluetooth": {
"version": "0.0.16",
"resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
},
"@types/webpack": { "@types/webpack": {
"version": "4.41.32", "version": "4.41.32",
"resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.32.tgz", "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.32.tgz",
@ -2338,18 +2378,25 @@
"dev": true "dev": true
}, },
"@vueuse/core": { "@vueuse/core": {
"version": "7.7.1", "version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-7.7.1.tgz", "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-9.13.0.tgz",
"integrity": "sha512-PRRgbATMpoeUmkCEBtUeJgOwtew8s+4UsEd+Pm7MhkjL2ihCNrSqxNVtM6NFE4uP2sWnkGcZpCjPuNSxowJ1Ow==", "integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==",
"requires": { "requires": {
"@vueuse/shared": "7.7.1", "@types/web-bluetooth": "^0.0.16",
"@vueuse/metadata": "9.13.0",
"@vueuse/shared": "9.13.0",
"vue-demi": "*" "vue-demi": "*"
} }
}, },
"@vueuse/metadata": {
"version": "9.13.0",
"resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.13.0.tgz",
"integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ=="
},
"@vueuse/shared": { "@vueuse/shared": {
"version": "7.7.1", "version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-7.7.1.tgz", "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.13.0.tgz",
"integrity": "sha512-rN2qd22AUl7VdBxihagWyhUNHCyVk9IpvBTTfHoLH9G7rGE552X1f+zeCfehuno0zXif13jPw+icW/wn2a0rnQ==", "integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==",
"requires": { "requires": {
"vue-demi": "*" "vue-demi": "*"
} }
@ -2909,7 +2956,7 @@
}, },
"async-validator": { "async-validator": {
"version": "4.2.5", "version": "4.2.5",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
"integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
}, },
"asynckit": { "asynckit": {
@ -4965,9 +5012,9 @@
"dev": true "dev": true
}, },
"dayjs": { "dayjs": {
"version": "1.11.4", "version": "1.11.18",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.4.tgz", "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.18.tgz",
"integrity": "sha512-Zj/lPM5hOvQ1Bf7uAvewDaUcsJoI6JmNqmHhHl3nyumwe0XHwt8sWdOVAPACJzCebL8gQCi+K49w7iKWnGwX9g==" "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA=="
}, },
"debug": { "debug": {
"version": "4.3.4", "version": "4.3.4",
@ -5525,21 +5572,25 @@
"dev": true "dev": true
}, },
"element-plus": { "element-plus": {
"version": "2.0.2", "version": "2.11.3",
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.0.2.tgz", "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.11.3.tgz",
"integrity": "sha512-URjC0HwwiqtlLxqTmHXQ31WXrdAq4ChWyyn52OcQs3PRsnMPfahGVq2AWnfzzlzlhVeI5lY3HQiuB1zDathS+g==", "integrity": "sha512-769xsjLR4B9Vf9cl5PDXnwTEdmFJvMgAkYtthdJKPhjVjU3hdAwTJ+gXKiO+PUyo2KWFwOYKZd4Ywh6PHfkbJg==",
"requires": { "requires": {
"@ctrl/tinycolor": "^3.4.0", "@ctrl/tinycolor": "^3.4.1",
"@element-plus/icons-vue": "^0.2.6", "@element-plus/icons-vue": "^2.3.1",
"@popperjs/core": "^2.11.2", "@floating-ui/dom": "^1.0.1",
"@vueuse/core": "^7.6.0", "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
"async-validator": "^4.0.7", "@types/lodash": "^4.14.182",
"dayjs": "^1.10.7", "@types/lodash-es": "^4.17.6",
"@vueuse/core": "^9.1.0",
"async-validator": "^4.2.5",
"dayjs": "^1.11.13",
"escape-html": "^1.0.3",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"lodash-unified": "^1.0.1", "lodash-unified": "^1.0.2",
"memoize-one": "^6.0.0", "memoize-one": "^6.0.0",
"normalize-wheel-es": "^1.1.1" "normalize-wheel-es": "^1.2.0"
} }
}, },
"elliptic": { "elliptic": {
@ -5714,8 +5765,7 @@
"escape-html": { "escape-html": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
"dev": true
}, },
"escape-string-regexp": { "escape-string-regexp": {
"version": "1.0.5", "version": "1.0.5",
@ -9006,13 +9056,13 @@
}, },
"lodash-es": { "lodash-es": {
"version": "4.17.21", "version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
}, },
"lodash-unified": { "lodash-unified": {
"version": "1.0.2", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.2.tgz", "resolved": "https://registry.npmmirror.com/lodash-unified/-/lodash-unified-1.0.3.tgz",
"integrity": "sha512-OGbEy+1P+UT26CYi4opY4gebD8cWRDxAT6MAObIVQMiqYdxZr1g3QHWCToVsm31x2NkLS4K3+MC2qInaRMa39g==" "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ=="
}, },
"lodash.debounce": { "lodash.debounce": {
"version": "4.0.8", "version": "4.0.8",
@ -9217,7 +9267,7 @@
}, },
"memoize-one": { "memoize-one": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
}, },
"memory-fs": { "memory-fs": {
@ -9720,7 +9770,7 @@
}, },
"normalize-wheel-es": { "normalize-wheel-es": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz", "resolved": "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
"integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==" "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw=="
}, },
"npm-run-path": { "npm-run-path": {
@ -14624,9 +14674,9 @@
"dev": true "dev": true
}, },
"vue-demi": { "vue-demi": {
"version": "0.13.6", "version": "0.14.10",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.6.tgz", "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz",
"integrity": "sha512-02NYpxgyGE2kKGegRPYlNQSL1UWfA/+JqvzhGCOYjhfbLWXU5QQX0+9pAm/R2sCOPKr5NBxVIab7fvFU0B1RxQ==" "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg=="
}, },
"vue-eslint-parser": { "vue-eslint-parser": {
"version": "7.11.0", "version": "7.11.0",

View File

@ -20,7 +20,7 @@
"core-js": "^3.6.5", "core-js": "^3.6.5",
"echarts": "^5.3.3", "echarts": "^5.3.3",
"echarts-gl": "^2.0.9", "echarts-gl": "^2.0.9",
"element-plus": "2.0.2", "element-plus": "2.11.3",
"gifler": "^0.1.0", "gifler": "^0.1.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mitt": "^3.0.0", "mitt": "^3.0.0",

View File

@ -1,5 +1,5 @@
import request from "@/utils/request"; import request from "@/utils/request";
const api = "/mosty-base"; const api = "/mosty-api/mosty-base";
/* /*
* 登录 * 登录
* return promise 实例对象 * return promise 实例对象

View File

@ -54,7 +54,7 @@
import { COMPONENT_WIDTH } from "@/constant"; import { COMPONENT_WIDTH } from "@/constant";
import { ref, defineProps, defineEmits, defineExpose, computed, watch, onMounted } from "vue"; import { ref, defineProps, defineEmits, defineExpose, computed, watch, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage, ElMessageBox } from "element-plus";
import type from "element-plus/es/components/upload/src/upload.type";
import { useStore } from "vuex"; import { useStore } from "vuex";
const props = defineProps({ const props = defineProps({
//获取组件传值 //获取组件传值

View File

@ -19,9 +19,9 @@
</template> </template>
</el-dropdown> </el-dropdown>
</div> </div>
<div @click="goToHome"> <!-- <div @click="goToHome">
<img src="@/assets/images/meun.png" /> <img src="@/assets/images/meun.png" />
</div> </div> -->
</div> </div>
</header> </header>
</template> </template>

View File

@ -326,12 +326,52 @@ export const publicRoutes = [
}, },
}, },
{ {
path: "/trainer", path: "/trainingManagement",
name: "trainer", name: "/trainingManagement",
component: () =>
import("@/views/securityManagement/trainer/index"),
meta: { meta: {
title: "培训人员管理", title: "培训管理",
icon: "personnel"
},
children: [
{
path: "/trainingManagement/trainer",
name: "trainer",
component: () =>
import("@/views/securityManagement/trainingManagement/trainer/index"),
meta: {
title: "培训人员",
icon: "personnel"
},
},
{
path: "/trainingManagement/personnelTraining",
name: "personnelTraining",
component: () =>
import("@/views/securityManagement/trainingManagement/personnelTraining/index"),
meta: {
title: "保安待培训人员管理",
icon: "personnel"
},
},
{
path: "/trainingManagement/trainingProject",
name: "trainingProject",
component: () =>
import("@/views/securityManagement/trainingManagement/trainingProject/index"),
meta: {
title: "保安培训项目管理",
icon: "personnel"
}
}
]
},
{
path: "/examManagement",
name: "examManagement",
component: () =>
import("@/views/securityManagement/examManagement/index"),
meta: {
title: "保安考试管理",
icon: "personnel" icon: "personnel"
}, },
} }

View File

@ -97,6 +97,13 @@ div:focus {
border-color: rgb(8, 85, 170); border-color: rgb(8, 85, 170);
} }
::v-deep {
.el-input__inner, .el-input__inner:hover, .el-input__inner:focus {
border: none;
box-shadow: none;
}
}
.new-btn-class-bj { .new-btn-class-bj {
color: #409eff; color: #409eff;
margin-right: 10px; margin-right: 10px;

View File

@ -0,0 +1,83 @@
<template>
<el-dialog class="dialogWerapper" v-model="modelValue" :title="title" @close="handleClose">
<form-message ref="FormRef" v-model="formData" :rules="rules" :formList="formList" />
<template #footer>
<el-button type="primary" :loading="loading" @click="handleSubmit">确定</el-button>
<el-button @click="handleClose">取消</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { computed, ref, reactive } from 'vue';
import FormMessage from '@/components/aboutTable/FormMessage.vue'
const props = defineProps({
title: {
type: String,
default: '上传成绩'
},
modelValue: {
type: Boolean,
default: false
},
})
const emits = defineEmits(['update:modelValue'])
const visible = computed({
get() {
return props.modelValue
},
set(val) {
emits('update:modelValue', val)
}
})
const loading = ref(false)
const FormRef = ref(null)
const formData = ref({})
const formList = reactive([
[
{ label: "成绩", prop: "cj", type: "input" },
],
[
{ label: "卷面", prop: "ssbmdm", type: "upload", limit: 1 },
],
])
const rules = {
cj: [{ required: true, message: "请输入考试成绩", trigger: "change" }],
sfzh: [{ required: true, message: "请输入证件号码", trigger: "change" }],
}
const handleClose = () => {
visible.value = false
}
const handleSubmit = () => {
try {
loading.value = true
FormRef.value.submit(res => {
console.log(res)
visible.value = false
})
} catch (error) {
console.log(error)
} finally {
loading.value = false
}
}
</script>
<style lang="scss" scoped>
::v-deep {
.dialogWerapper {
.el-dialog__header {
background: none !important;
}
}
}
</style>

View File

@ -0,0 +1,155 @@
<template>
<div class="dialog" v-if="dialogVisible">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<el-button size="small" @click="save" type="primary" :loading="loading">保存</el-button>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="cntinfo">
<el-descriptions column="2" border>
<el-descriptions-item label="培训项目名称">{{ formData.xm }}</el-descriptions-item>
<el-descriptions-item label="考试时间">{{ formData.sfzh }}</el-descriptions-item>
<el-descriptions-item label="考试辖区">{{ formData.lxdh }}</el-descriptions-item>
<el-descriptions-item label="考试地址">{{ formData.jzdz }}</el-descriptions-item>
<el-descriptions-item label="监考民警">{{ formData.rzsj }}</el-descriptions-item>
<el-descriptions-item label="考试方式">{{ formData.ssbmdm }}</el-descriptions-item>
</el-descriptions>
<!-- <el-descriptions title="考试人员" column="2" border class="mt20"> -->
<div class="label">考试人员</div>
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('updata', row)">上传成绩</el-link>
<el-link type="primary" @click="addEdit('view', row)">查看成绩</el-link>
</template>
</MyTable>
<!-- </el-descriptions> -->
<view-and-upload-dialog v-model="viewAndUploadVisible" />
</div>
</div>
</template>
<script setup>
import { ref, computed, reactive, getCurrentInstance } from 'vue'
import { qcckPost } from "@/api/qcckApi.js";
import MyTable from '@/components/aboutTable/MyTable.vue';
import viewAndUploadDialog from './viewAndUploadDialog.vue';
const { proxy } = getCurrentInstance()
const title = ref('保安线下考试详情')
const loading = ref(false)
const disabled = ref(false)
const FormRef = ref(null)
const viewAndUploadVisible = ref(true)
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
dic: {
type: Object,
default: () => ({})
}
})
const emits = defineEmits(['update:modelValue'])
const dialogVisible = computed({
get() {
return props.modelValue
},
set(val) {
emits('update:modelValue', val)
}
})
const pageData = reactive({
tableData: [{}],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
},
controlsWidth: 180,
tableColumn: [
{ label: "姓名", prop: "xm" },
{ label: "证件号码", prop: "sfzh" },
{ label: "联系方式", prop: "lxdh" },
{ label: "线上培训时间", prop: "sfzh" },
{ label: "线下培训课程", prop: "lxdh" },
{ label: "考试成绩", prop: "lxdh" },
]
});
const formData = ref({})
const close = () => {
dialogVisible.value = false
}
const open = (row = {}, type = 'add') => {
disabled.value = false
dialogVisible.value = true
formData.value = { ...row }
if (type === 'add') {
title.value = '新增从业人员'
} else if (type === 'edit') {
title.value = '编辑从业人员'
} else {
disabled.value = true
title.value = '查看详情'
}
}
const save = () => {
FormRef.value.submit(() => {
loading.value = true;
const url = !formData.value?.id ? `/mosty-base/baxx/cyry/add` : `/mosty-base/baxx/cyry/edit`;
qcckPost(formData.value, url).then(() => {
loading.value = false;
proxy.$message.success("保存成功");
emits("refresh");
close();
}).catch(() => {
loading.value = false;
})
});
}
defineExpose({ open })
</script>
<style lang="scss" scoped>
@import "@/assets/css/layout.scss";
.label {
margin-top: 20px;
color: #000;
}
.cntinfo {
padding: 2rem 12rem 0rem 12rem;
height: calc(100% - 70px);
overflow: hidden;
overflow-y: auto;
}
.mapBox {
width: 100%;
height: 400px;
overflow: hidden;
}
</style>

View File

@ -0,0 +1,131 @@
<template>
<div>
<div class="titleBox">
<page-title title="保安考试管理" />
</div>
<!-- 搜索 -->
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch"></Search>
</div>
<!-- 表格 -->
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #bxxLx="{ row }">
<DictTag :value="row.bxxLx" :tag="false" :options="D_BZ_BXDLX" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('view', row)">详情</el-link>
<el-link type="primary" @click="addEdit('edit', row)">证件申请</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"></Pages>
</div>
<!-- 线下线上考试详情 -->
<view-exam-detalis v-model="isVisible" ref="trainerRef" @refresh="getList" />
</div>
</template>
<script setup>
import { onMounted, reactive, ref } from "vue";
import MyTable from '@/components/aboutTable/MyTable.vue';
import Pages from '@/components/aboutTable/Pages.vue';
import Search from '@/components/aboutTable/Search.vue';
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
import PageTitle from "@/components/aboutTable/PageTitle.vue";
import ViewExamDetalis from "./components/viewExamDetalis.vue";
// import AddTrainerDialog from "./components/addTrainerDialog.vue";
const trainerRef = ref(null);
const queryFrom = ref({});
const isVisible = ref(true);
const searchBox = ref(null);
const D_BZ_BXDLX = ref([]);
const searchConfiger = ref([
{
label: "培训项目名称",
prop: "xm",
placeholder: "请输入培训项目名称",
showType: "input"
},
{
label: "考试时间",
prop: "sfzh",
placeholder: "请选择考试时间",
showType: "date"
},
]);
const pageData = reactive({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
},
controlsWidth: 180,
tableColumn: [
{ label: "培训项目名称", prop: "xm" },
{ label: "考试时间", prop: "sfzh" },
{ label: "监考民警", prop: "sfzh" },
{ label: "考试地址", prop: "sfzh" },
{ label: "考试方式", prop: "lxdh" },
]
});
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight =
window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
const addEdit = (type, row) => {
trainerRef.value.open(row, type);
};
const onSearch = (value) => {
queryFrom.value = value
pageData.pageConfiger.pageCurrent = 1;
getList();
}
const getList = async () => {
try {
pageData.tableConfiger.loading = true;
const res = await qcckPost({
...pageData.pageConfiger,
...queryFrom.value
}, `/mosty-base/baxx/pxry/page`)
if(res) {
pageData.tableData = res.records || [];
pageData.total = res.total;
}
} finally {
pageData.tableConfiger.loading = false;
}
}
onMounted(() => {
tabHeightFn();
getList();
});
</script>
<style scoped lang="scss">
</style>

View File

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<div class="titleBox"> <div class="titleBox">
<PageTitle title="从业人员管理" /> <page-title title="从业人员管理" />
<el-button type="primary" @click="addEdit('add', row)">新增</el-button> <el-button type="primary" @click="addEdit('add', row)">新增</el-button>
</div> </div>
<!-- 搜索 --> <!-- 搜索 -->
@ -41,8 +41,9 @@ import { onMounted, reactive, ref } from "vue";
import MyTable from '@/components/aboutTable/MyTable.vue'; import MyTable from '@/components/aboutTable/MyTable.vue';
import Pages from '@/components/aboutTable/Pages.vue'; import Pages from '@/components/aboutTable/Pages.vue';
import Search from '@/components/aboutTable/Search.vue'; import Search from '@/components/aboutTable/Search.vue';
import PageTitle from "@/components/aboutTable/PageTitle.vue";
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js"; import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
import addPractitionerDialog from "./components/addPractitionerDialog.vue"; import AddPractitionerDialog from "./components/addPractitionerDialog.vue";
const addPractitionerRef = ref(null); const addPractitionerRef = ref(null);
const queryFrom = ref({}); const queryFrom = ref({});

View File

@ -0,0 +1,100 @@
<template>
<div class="dialog" v-if="dialogVisible">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<!-- <el-button size="small" @click="save" type="primary" :loading="loading">保存</el-button> -->
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="cntinfo">
<el-descriptions column="2" border>
<el-descriptions-item label="姓名">{{ formData.xm }}</el-descriptions-item>
<el-descriptions-item label="身份证号">{{ formData.sfzh }}</el-descriptions-item>
<el-descriptions-item label="联系电话">{{ formData.lxdh }}</el-descriptions-item>
<el-descriptions-item label="所属保安公司">{{ formData.jzdz }}</el-descriptions-item>
<el-descriptions-item label="线上培训时长">{{ formData.rzsj }}</el-descriptions-item>
<el-descriptions-item label="提交日期">{{ formData.ssbmdm }}</el-descriptions-item>
</el-descriptions>
</div>
</div>
</template>
<script setup>
import { ref, computed, getCurrentInstance } from 'vue'
import { qcckPost } from "@/api/qcckApi.js";
const { proxy } = getCurrentInstance()
const title = ref('保安考试申请')
const loading = ref(false)
const disabled = ref(false)
const FormRef = ref(null)
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
dic: {
type: Object,
default: () => ({})
}
})
const emits = defineEmits(['update:modelValue'])
const dialogVisible = computed({
get() {
return props.modelValue
},
set(val) {
emits('update:modelValue', val)
}
})
const formData = ref({})
const close = () => {
dialogVisible.value = false
}
const open = (row = {}, type = 'add') => {
disabled.value = false
dialogVisible.value = true
formData.value = { ...row }
}
const save = () => {
FormRef.value.submit(() => {
loading.value = true;
const url = !formData.value?.id ? `/mosty-base/baxx/cyry/add` : `/mosty-base/baxx/cyry/edit`;
qcckPost(formData.value, url).then(() => {
loading.value = false;
proxy.$message.success("保存成功");
emits("refresh");
close();
}).catch(() => {
loading.value = false;
})
});
}
defineExpose({ open })
</script>
<style lang="scss" scoped>
@import "@/assets/css/layout.scss";
.cntinfo {
padding: 2rem 12rem 0rem 12rem;
height: calc(100% - 70px);
overflow: hidden;
overflow-y: auto;
}
.mapBox {
width: 100%;
height: 400px;
overflow: hidden;
}
</style>

View File

@ -0,0 +1,142 @@
<template>
<div>
<div class="titleBox">
<page-title title="保安待培训人员管理" />
</div>
<!-- 搜索 -->
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch"></Search>
</div>
<!-- 表格 -->
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #bxxLx="{ row }">
<DictTag :value="row.bxxLx" :tag="false" :options="D_BZ_BXDLX" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="danger" @click="handleDelete([row.id])">删除</el-link>
<el-link type="warning" @click="addEdit('view', row)">详情</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"></Pages>
</div>
<view-info-dialog ref="trainerRef" v-model="isVisible" />
</div>
</template>
<script setup>
import { onMounted, reactive, ref } from "vue";
import MyTable from '@/components/aboutTable/MyTable.vue';
import Pages from '@/components/aboutTable/Pages.vue';
import Search from '@/components/aboutTable/Search.vue';
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
import PageTitle from "@/components/aboutTable/PageTitle.vue";
import viewInfoDialog from "./components/viewInfoDialog.vue";
const trainerRef = ref(null);
const queryFrom = ref({});
const isVisible = ref(false);
const searchBox = ref(null);
const D_BZ_BXDLX = ref([]);
const searchConfiger = ref([
{
label: "姓名",
prop: "xm",
placeholder: "请输入人员姓名",
showType: "input"
},
{
label: "联系电话",
prop: "lxdh",
placeholder: "请输入联系电话",
showType: "input"
},
{
label: "所属保安公司",
prop: "sfzh",
placeholder: "请选择所属保安公司",
showType: "select"
},
{
label: "提交日期",
prop: "sfzh",
placeholder: "请选择提交日期",
showType: "date"
}
]);
const pageData = reactive({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
},
controlsWidth: 180,
tableColumn: [
{ label: "姓名", prop: "xm" },
{ label: "身份证号", prop: "sfzh" },
{ label: "联系方式", prop: "lxdh" },
{ label: "所属保安公司", prop: "pxgs" },
{ label: "线上培训时长", prop: "pxgs" },
{ label: "提交日期", prop: "pxgs" },
]
});
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight =
window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
const addEdit = (type, row) => {
trainerRef.value.open(row, type);
};
const onSearch = (value) => {
queryFrom.value = value
pageData.pageConfiger.pageCurrent = 1;
getList();
}
const getList = async () => {
try {
pageData.tableConfiger.loading = true;
const res = await qcckPost({
...pageData.pageConfiger,
...queryFrom.value
}, `/mosty-base/baxx/pxry/page`)
if(res) {
pageData.tableData = res.records || [];
pageData.total = res.total;
}
} finally {
pageData.tableConfiger.loading = false;
}
}
onMounted(() => {
tabHeightFn();
getList();
});
</script>
<style scoped lang="scss">
</style>

View File

@ -57,12 +57,14 @@ const formList = reactive([
{ label: "姓名", prop: "xm", type: "input" }, { label: "姓名", prop: "xm", type: "input" },
{ label: "证件号码", prop: "sfzh", type: "select", options: props.dic.D_BZ_BXDLX }, { label: "证件号码", prop: "sfzh", type: "select", options: props.dic.D_BZ_BXDLX },
{ label: "联系电话", prop: "lxdh", type: "input" }, { label: "联系电话", prop: "lxdh", type: "input" },
{ label: "居住地址", prop: "jzdz", type: "input" },
], ],
[ [
{ label: "居住地址", prop: "jzdz", type: "input" },
{ label: "申请时间", prop: "rzsj", type: "date" }, { label: "申请时间", prop: "rzsj", type: "date" },
{ label: "岗位", prop: "ssbmdm", type: "select" }, { label: "岗位", prop: "ssbmdm", type: "select" },
{ label: "所属保安公司", prop: "pxgs", type: "input" }, ],
[
{ label: "所属保安公司", prop: "pxgs", type: "select" },
], ],
[ [
{ label: "身份证正反面", prop: "ssbmdm", type: "upload", limit: 2 }, { label: "身份证正反面", prop: "ssbmdm", type: "upload", limit: 2 },

View File

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<div class="titleBox"> <div class="titleBox">
<PageTitle title="培训人员管理" /> <page-title title="培训人员管理" />
<el-button type="primary" @click="addEdit('add', row)">新增</el-button> <el-button type="primary" @click="addEdit('add', row)">新增</el-button>
</div> </div>
<!-- 搜索 --> <!-- 搜索 -->
@ -39,7 +39,8 @@ import MyTable from '@/components/aboutTable/MyTable.vue';
import Pages from '@/components/aboutTable/Pages.vue'; import Pages from '@/components/aboutTable/Pages.vue';
import Search from '@/components/aboutTable/Search.vue'; import Search from '@/components/aboutTable/Search.vue';
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js"; import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
import addTrainerDialog from "./components/addTrainerDialog.vue"; import PageTitle from "@/components/aboutTable/PageTitle.vue";
import AddTrainerDialog from "./components/addTrainerDialog.vue";
const trainerRef = ref(null); const trainerRef = ref(null);
const queryFrom = ref({}); const queryFrom = ref({});

View File

@ -0,0 +1,130 @@
<template>
<div>
<div class="titleBox">
<page-title title="保安培训项目管理" />
<el-button type="primary" @click="addEdit('add', row)">新增</el-button>
</div>
<!-- 搜索 -->
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch"></Search>
</div>
<!-- 表格 -->
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #bxxLx="{ row }">
<DictTag :value="row.bxxLx" :tag="false" :options="D_BZ_BXDLX" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('view', row)">详情</el-link>
<el-link type="primary" @click="addEdit('edit', row)">考试申请</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"></Pages>
</div>
<!-- <add-trainer-dialog v-model="isVisible" ref="trainerRef" @refresh="getList" /> -->
</div>
</template>
<script setup>
import { onMounted, reactive, ref } from "vue";
import MyTable from '@/components/aboutTable/MyTable.vue';
import Pages from '@/components/aboutTable/Pages.vue';
import Search from '@/components/aboutTable/Search.vue';
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
import PageTitle from "@/components/aboutTable/PageTitle.vue";
// import AddTrainerDialog from "./components/addTrainerDialog.vue";
const trainerRef = ref(null);
const queryFrom = ref({});
const isVisible = ref(false);
const searchBox = ref(null);
const D_BZ_BXDLX = ref([]);
const searchConfiger = ref([
{
label: "培训项目名称",
prop: "xm",
placeholder: "请输入培训项目名称",
showType: "input"
},
{
label: "培训开始时间",
prop: "sfzh",
placeholder: "请选择培训开始时间",
showType: "date"
},
]);
const pageData = reactive({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
},
controlsWidth: 180,
tableColumn: [
{ label: "培训项目名称", prop: "xm" },
{ label: "培训开始时间", prop: "sfzh" },
{ label: "培训结束时间", prop: "sfzh" },
{ label: "培训公司", prop: "sfzh" },
{ label: "培训地址", prop: "lxdh" },
]
});
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight =
window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
const addEdit = (type, row) => {
trainerRef.value.open(row, type);
};
const onSearch = (value) => {
queryFrom.value = value
pageData.pageConfiger.pageCurrent = 1;
getList();
}
const getList = async () => {
try {
pageData.tableConfiger.loading = true;
const res = await qcckPost({
...pageData.pageConfiger,
...queryFrom.value
}, `/mosty-base/baxx/pxry/page`)
if(res) {
pageData.tableData = res.records || [];
pageData.total = res.total;
}
} finally {
pageData.tableConfiger.loading = false;
}
}
onMounted(() => {
tabHeightFn();
getList();
});
</script>
<style scoped lang="scss">
</style>

View File

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<div class="titleBox"> <div class="titleBox">
<PageTitle title="单位管理" /> <page-title title="单位管理" />
<el-button type="primary" @click="addEdit('add', row)">新增</el-button> <el-button type="primary" @click="addEdit('add', row)">新增</el-button>
</div> </div>
<!-- 搜索 --> <!-- 搜索 -->
@ -25,6 +25,7 @@
<el-link type="warning" @click="handleXfrw(row)">下发任务</el-link> <el-link type="warning" @click="handleXfrw(row)">下发任务</el-link>
</template> </template>
</MyTable> </MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{ <Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger, ...pageData.pageConfiger,
total: pageData.total total: pageData.total
@ -38,6 +39,7 @@ import { onMounted, reactive, ref } from "vue";
import MyTable from '@/components/aboutTable/MyTable.vue'; import MyTable from '@/components/aboutTable/MyTable.vue';
import Pages from '@/components/aboutTable/Pages.vue'; import Pages from '@/components/aboutTable/Pages.vue';
import Search from '@/components/aboutTable/Search.vue'; import Search from '@/components/aboutTable/Search.vue';
import PageTitle from '@/components/aboutTable/PageTitle.vue';
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js"; import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
const searchBox = ref(null); const searchBox = ref(null);

View File

@ -4,8 +4,8 @@ function resolve(dir) {
return path.join(__dirname, dir); return path.join(__dirname, dir);
} }
// const serverHost = "http://192.168.1.98:8006";//毛毛 // const serverHost = "http://192.168.1.98:8006";//毛毛
const serverHost = "http://192.168.1.32:8066";//波哥 // const serverHost = "http://192.168.1.32:8066";//波哥
// const serverHost = "http://192.168.0.231:8006"//线上 const serverHost = "http://192.168.0.231:8006"//线上
// const serverHost = "http://47.108.232.77:9537";//波哥 // const serverHost = "http://47.108.232.77:9537";//波哥
// const serverHost = "http://127.0.0.1:8006" // const serverHost = "http://127.0.0.1:8006"
module.exports = { module.exports = {