123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698 |
- <template>
- <div class="ip-config">
- <div class="box box-info">
- <div class="box-body">
- <el-form
- ref="formSearch"
- :model="formSearch"
- :inline="true"
- label-width="70px"
- >
- <el-form-item label="学习中心">
- <el-select
- v-model="formSearch.orgId"
- class="input"
- filterable
- clearable
- placeholder="请选择"
- >
- <el-option
- v-for="item in orgList4Search"
- :key="item.id"
- :label="item.name + ' - ' + item.code"
- :value="item.id"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button
- size="small"
- type="primary"
- icon="el-icon-search"
- @click="resetPageAndSearchForm"
- >查询</el-button
- >
- </el-form-item>
- </el-form>
- <div class="block-seperator"></div>
- <span>操作:</span>
- <el-button
- size="small"
- type="primary"
- icon="el-icon-plus"
- @click="editItem(null)"
- >新增</el-button
- >
- <el-button
- size="small"
- type="primary"
- icon="el-icon-upload2"
- @click="impCourse"
- >批量导入</el-button
- >
- <el-button
- size="small"
- type="danger"
- :disabled="!selectedIds.length"
- icon="el-icon-delete"
- @click="deleteMult(selectedIds)"
- >批量删除</el-button
- >
- <el-button
- v-if="rolePrivileges.ORG_IP_CONFIG_SYNC"
- size="small"
- type="success"
- @click="openSynchronousDialog"
- >同步到考试</el-button
- >
- <el-button
- size="small"
- type="primary"
- icon="el-icon-download"
- @click="exportHandler"
- >导出</el-button
- >
- <el-table
- :data="tableData"
- border
- style="width: 100%; text-align: center; margin-top: 10px"
- @selection-change="selectChange"
- >
- <el-table-column type="selection" width="50"></el-table-column>
- <el-table-column prop="ip" width label="IP/IP段"></el-table-column>
- <el-table-column
- prop="orgCode"
- width
- label="学习中心代码"
- ></el-table-column>
- <el-table-column
- prop="orgName"
- width
- label="学习中心"
- ></el-table-column>
- <el-table-column prop="remark" width label="备注"></el-table-column>
- <el-table-column
- prop="updateTime"
- width
- label="操作时间"
- ></el-table-column>
- <el-table-column
- prop="updateName"
- width
- label="操作人"
- ></el-table-column>
- <el-table-column label="操作" width="300">
- <div slot-scope="scope">
- <el-button
- size="mini"
- type="primary"
- plain
- @click="editItem(scope.row)"
- >编辑</el-button
- >
- <el-button
- size="mini"
- type="danger"
- plain
- @click="deleteItem(scope.row)"
- >删除</el-button
- >
- </div>
- </el-table-column>
- </el-table>
- <div class="page pull-right">
- <el-pagination
- :current-page="currentPage"
- :page-size="pageSize"
- :page-sizes="[10, 20, 50, 100, 200, 300]"
- layout="total, sizes, prev, pager, next, jumper"
- :total="total"
- @current-change="handleCurrentChange"
- @size-change="handleSizeChange"
- ></el-pagination>
- </div>
- </div>
- </div>
- <el-dialog
- title="同步到考试"
- width="400px"
- :visible.sync="showSynchronousDialog"
- :close-on-click-modal="false"
- >
- <el-form
- ref="synchronousRef"
- :model="synchronousForm"
- :rules="synchronousRules"
- label-width="80px"
- >
- <el-form-item label="选择考试" prop="examId">
- <el-select
- v-model="synchronousForm.examId"
- filterable
- placeholder="请选择"
- >
- <el-option
- v-for="item in examList"
- :key="item.id"
- :label="item.name"
- :value="item.id"
- ></el-option>
- </el-select>
- <div style="font-size: 12px; color: #e6a23c">
- 提示:只能选择开启了IP特殊设置的考试
- </div>
- </el-form-item>
- </el-form>
- <div slot="footer">
- <el-button @click="showSynchronousDialog = false">取消</el-button>
- <el-button type="primary" @click="synchronousSubmit">同步</el-button>
- </div>
- </el-dialog>
- <el-dialog
- :title="curRow ? '修改' : '新增'"
- width="450px"
- :visible.sync="showEditDialog"
- :close-on-click-modal="false"
- @close="dialogBeforeClose"
- >
- <el-form
- ref="editRef"
- :model="editForm"
- :rules="editRules"
- label-width="80px"
- >
- <el-form-item label="学习中心" prop="orgId">
- <el-select
- v-model="editForm.orgId"
- filterable
- clearable
- placeholder="请选择"
- >
- <el-option
- v-for="item in orgList4Search"
- :key="item.id"
- :label="item.name + ' - ' + item.code"
- :value="item.id"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="IP/IP段" prop="ip">
- <div style="display: flex; align-items: center">
- <el-input v-model="editForm.ip" placeholder="请输入IP或者IP段" />
- <el-button
- type="primary"
- style="margin-left: 10px"
- @click="getIpAddress"
- >获取本机ip</el-button
- >
- </div>
- </el-form-item>
- <el-form-item label="备注" prop="remark">
- <el-input
- v-model="editForm.remark"
- type="textarea"
- maxlength="100"
- placeholder="请填写考点地址"
- />
- </el-form-item>
- </el-form>
- <div slot="footer">
- <el-button @click="showEditDialog = false">取消</el-button>
- <el-button type="primary" @click="editSubmit">保存</el-button>
- </div>
- </el-dialog>
- <!-- 导入弹窗 -->
- <el-dialog
- title="导入窗口"
- width="520px"
- :visible.sync="impDialog"
- :close-on-click-modal="false"
- >
- <el-form>
- <el-row>
- <el-form-item style="margin-left: 20px">
- <el-upload
- ref="upload"
- class="form_left"
- accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
- :action="uploadAction"
- :headers="uploadHeaders"
- :data="uploadData"
- :before-upload="beforeUpload"
- :on-progress="uploadProgress"
- :on-success="uploadSuccess"
- :on-error="uploadError"
- :file-list="fileList"
- :auto-upload="false"
- :multiple="false"
- >
- <el-button
- slot="trigger"
- size="small"
- type="primary"
- icon="el-icon-search"
- >
- 选择文件
- </el-button>
-
- <el-button
- size="small"
- type="primary"
- icon="el-icon-check"
- @click="submitUpload"
- >
- 确认上传
- </el-button>
- <el-button
- size="small"
- type="primary"
- icon="el-icon-refresh"
- @click="removeFile"
- >
- 清空文件
- </el-button>
- <el-button
- size="small"
- type="primary"
- icon="el-icon-download"
- @click="exportFile"
- >
- 下载模板
- </el-button>
- <div slot="tip" class="el-upload__tip">只能上传xlsx文件</div>
- </el-upload>
- </el-form-item>
- </el-row>
- </el-form>
- </el-dialog>
- <!-- 导入错误信息列表 -->
- <el-dialog title="错误提示" :visible.sync="errDialog">
- <div
- v-for="errMessage in errMessages"
- :key="errMessage.lineNum"
- class="text-danger"
- >
- {{ errMessage }}
- </div>
- <span slot="footer" class="dialog-footer">
- <el-button @click="errDialog = false">确定</el-button>
- </span>
- </el-dialog>
- </div>
- </template>
- <script>
- import { CORE_API, EXAM_WORK_API } from "@/constants/constants.js";
- import { mapState } from "vuex";
- export default {
- name: "IpConfig",
- data() {
- return {
- rolePrivileges: {
- ORG_IP_CONFIG_SYNC: false,
- },
- examList: [],
- curRow: null,
- showSynchronousDialog: false,
- formSearch: {
- orgId: "",
- },
- getOrgList4SearchLoading: false,
- orgList4Search: [],
- tableData: [],
- currentPage: 1,
- pageSize: 10,
- total: 10,
- selectedIds: [],
- editForm: {
- orgId: "",
- ip: "",
- remark: "",
- },
- editRules: {
- orgId: [
- {
- required: true,
- message: "请选择学习中心",
- trigger: "blur",
- },
- ],
- ip: [
- {
- required: true,
- message: "请填写IP或IP段",
- trigger: "blur",
- },
- ],
- },
- synchronousForm: {
- examId: "",
- },
- synchronousRules: {
- examId: [
- {
- required: true,
- message: "请选择考试",
- trigger: "blur",
- },
- ],
- },
- showEditDialog: false,
- impDialog: false,
- uploadAction: EXAM_WORK_API + "/org/ip/import",
- uploadHeaders: {},
- uploadData: {},
- errMessages: [],
- errDialog: false,
- fileLoading: false,
- loading: false,
- fileList: [],
- };
- },
- computed: {
- ...mapState({ user: (state) => state.user }),
- },
- created() {
- this.initPrivileges();
- this.getOrgList4Search("");
- this.searchForm();
- this.getExamList();
- this.uploadHeaders = {
- key: this.user.key,
- token: this.user.token,
- };
- },
- methods: {
- initPrivileges() {
- let params = new URLSearchParams();
- params.append(
- "privilegeCodes",
- Object.keys(this.rolePrivileges).toString()
- );
- var url = CORE_API + "/rolePrivilege/checkPrivileges?" + params;
- this.$httpWithMsg.post(url).then((response) => {
- this.rolePrivileges = response.data;
- });
- },
- dialogBeforeClose() {
- this.$refs.editRef.clearValidate();
- },
- getExamList() {
- this.$httpWithMsg
- .get(
- EXAM_WORK_API +
- "/exam/queryByNameLike?enable=true&propertyKeys=IP_LIMIT&name=" +
- name
- )
- .then((response) => {
- this.examList = (response.data || []).filter((item) => {
- return item?.properties?.IP_LIMIT == "true";
- });
- });
- },
- getIpAddress() {
- // let year = new Date().getFullYear();
- // fetch(`https://${year}.ip138.com/`)
- // .then((x) => x.text())
- // .then((h) => {
- // let domParser = new DOMParser();
- // let doc = domParser.parseFromString(h, "text/html");
- // let text = doc?.querySelector("p")?.innerText?.trim();
- // let ip = text
- // .substring(text.indexOf("[") + 1, text.indexOf("]"))
- // .trim();
- // this.editForm.ip = ip;
- // });
- fetch("https://qifu-api.baidubce.com/ip/local/geo/v1/district")
- .then((res) => res.json())
- .then((res) => {
- this.editForm.ip = res?.ip || "";
- });
- },
- editSubmit() {
- this.$refs.editRef.validate((valid) => {
- if (valid) {
- let path = this.curRow ? "/org/ip/update" : "/org/ip/save";
- let url = EXAM_WORK_API + path;
- let data = {
- ...this.editForm,
- // ip: encodeURIComponent(this.editForm.ip),
- };
- if (this.curRow) {
- data.id = this.curRow.id;
- }
- this.$httpWithMsg
- .post(url, null, {
- params: data,
- })
- .then(() => {
- this.$notify({
- type: "success",
- message: (this.curRow ? "修改" : "新增") + "成功!",
- });
- this.resetPageAndSearchForm();
- this.showEditDialog = false;
- });
- }
- });
- },
- openSynchronousDialog() {
- this.synchronousForm.examId = "";
- this.showSynchronousDialog = true;
- },
- synchronousSubmit() {
- // this.showSynchronousDialog = false;
- this.$refs.synchronousRef.validate((valid) => {
- if (valid) {
- this.$httpWithMsg
- .post(EXAM_WORK_API + "/org/ip/exam/add", null, {
- params: { ...this.synchronousForm },
- })
- .then(() => {
- this.$notify({
- type: "success",
- message: "同步成功!",
- });
- this.resetPageAndSearchForm();
- this.showSynchronousDialog = false;
- });
- }
- });
- },
- getOrgList4Search(orgName) {
- this.getOrgList4SearchLoading = true;
- let url =
- CORE_API +
- "/org/query?rootOrgId=" +
- this.user.rootOrgId +
- "&name=" +
- orgName;
- this.$httpWithMsg
- .get(url)
- .then((response) => {
- this.getOrgList4SearchLoading = false;
- this.orgList4Search = response.data;
- })
- .catch((response) => {
- console.log(response);
- this.getOrgList4SearchLoading = false;
- });
- },
- resetPageAndSearchForm() {
- this.currentPage = 1;
- this.searchForm();
- },
- searchForm() {
- let url = EXAM_WORK_API + "/org/ip/page";
- this.$httpWithMsg
- .post(url, null, {
- params: {
- ...this.formSearch,
- pageNumber: this.currentPage,
- pageSize: this.pageSize,
- },
- headers: {
- "content-type": "application/x-www-form-urlencoded",
- },
- })
- .then((response) => {
- this.tableData = response.data.list;
- this.total = response.data.total;
- });
- },
- handleCurrentChange(val) {
- this.currentPage = val;
- this.searchForm();
- },
- handleSizeChange(val) {
- this.pageSize = val;
- this.searchForm();
- },
- editItem(item) {
- if (!item) {
- this.editForm = {
- orgId: "",
- ip: "",
- remark: "",
- };
- }
- if (item) {
- this.editForm.orgId = item?.orgId;
- this.editForm.ip = item?.ip;
- this.editForm.remark = item?.remark;
- }
- this.curRow = item;
- this.showEditDialog = true;
- },
- deleteItem(item) {
- console.log(item);
- this.deleteMult([item.id], true);
- },
- deleteMult(ids, bool) {
- let str = bool ? "是否删除该条数据?" : "是否删除所选数据?";
- this.$confirm(str, "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- }).then(() => {
- var url = EXAM_WORK_API + "/org/ip/delete";
- this.$httpWithMsg
- // .post(url, qs.stringify({ ids: ids.join(",") }), {
- .post(url, ids, {
- headers: {
- "content-type": "application/json",
- },
- })
- .then(() => {
- this.$notify({
- type: "success",
- message: "删除成功!",
- });
- this.searchForm();
- });
- });
- },
- selectChange(rows) {
- this.selectedIds = rows.map((item) => item.id);
- }, //导入
- impCourse() {
- this.impDialog = true;
- this.initUpload();
- },
- initUpload() {
- this.fileList = [];
- },
- beforeUpload(file) {
- console.log(file);
- },
- uploadProgress() {
- console.log("uploadProgress");
- },
- uploadSuccess(response) {
- if (!response.hasError) {
- this.$notify({
- message: "上传成功",
- type: "success",
- });
- this.fileLoading = false;
- this.impDialog = false;
- this.searchForm();
- } else {
- this.fileLoading = false;
- this.impDialog = false;
- this.errMessages = response.failRecords;
- this.errDialog = true;
- }
- },
- uploadError(response) {
- var json = JSON.parse(response.message);
- if (response.status == 500) {
- this.$notify({
- message: json.desc,
- type: "error",
- });
- }
- this.fileLoading = false;
- },
- //确定上传
- submitUpload() {
- if (!this.checkUpload()) {
- return false;
- }
- this.$refs.upload.submit();
- this.fileLoading = true;
- },
- checkUpload() {
- var fileList = this.$refs.upload.uploadFiles;
- if (fileList.length == 0) {
- this.$notify({
- message: "上传文件不能为空",
- type: "error",
- });
- return false;
- }
- if (fileList.length > 1) {
- this.$notify({
- message: "每次只能上传一个文件",
- type: "error",
- });
- return false;
- }
- for (let file of fileList) {
- if (!file.name.endsWith(".xlsx")) {
- this.$notify({
- message: "上传文件必须为xlsx格式",
- type: "error",
- });
- this.initUpload();
- return false;
- }
- }
- return true;
- },
- //清空文件
- removeFile() {
- // this.fileList = [];
- this.$refs.upload.clearFiles();
- },
- //下载模板
- exportFile() {
- window.location.href =
- EXAM_WORK_API +
- "/org/ip/template?$key=" +
- this.user.key +
- "&$token=" +
- this.user.token;
- },
- exportHandler() {
- var param = new URLSearchParams(this.formSearch);
- window.open(
- EXAM_WORK_API +
- "/org/ip/export" +
- "?$key=" +
- this.user.key +
- "&$token=" +
- this.user.token +
- "&" +
- param
- );
- },
- },
- };
- </script>
- <style lang="scss" scoped>
- .ip-config {
- margin-top: 0 !important;
- .el-dialog__body {
- .el-form-item {
- margin-bottom: 15px !important;
- :deep(.el-form-item__label) {
- margin-bottom: 2px !important;
- }
- }
- }
- }
- </style>
|