管理平台功能升级

This commit is contained in:
2026-06-04 16:20:45 +08:00
parent 86a383e719
commit d2d31b4bc5
43 changed files with 3533 additions and 56 deletions

View File

@@ -33,11 +33,15 @@ export default {
editBdCard: "/accountManager/editBdCard",
// 删除北斗卡
deleteBdCard: "/accountManager/deleteBdCard",
// 管理系统导出北斗卡
downloadBDCard: "/accountManager/downloadBDCard",
// 查看绑定记录
showBindRecord: "/accountManager/showBindRecord",
// 删除绑定记录
deleteBindRecord: "/accountManager/deleteBindRecord",
// 管理系统导出绑定记录
downloadBindRecord: "/accountManager/downloadBindRecord",
// 注册公司业务
addBusiness: "/accountManager/addBusiness",
@@ -49,6 +53,8 @@ export default {
editBusiness: "/accountManager/editBusiness",
// 删除公司业务
deleteBusiness: "/accountManager/deleteBusiness",
// 管理系统导出公司业务
downloadBusiness: "/accountManager/downloadBusiness",
// 注册B端用户
addBSide: "/accountManager/addBSide",
@@ -58,6 +64,8 @@ export default {
editBSide: "/accountManager/editBSide",
// 删除B端用户
deleteBSide: "/accountManager/deleteBSide",
// 管理系统导出B端用户
downloadBside: "/accountManager/downloadBside",
// 查看C端用户
showCSide: "/accountManager/showCSide",
@@ -65,6 +73,8 @@ export default {
editCSide: "/accountManager/editCSide",
// 删除C端用户
deleteCSide: "/accountManager/deleteCSide",
// 管理系统导出C端用户
downloadCside: "/accountManager/downloadCside",
// 注册管理系统用户
addInsiders: "/accountManager/addInsiders",
@@ -74,6 +84,8 @@ export default {
editInsiders: "/accountManager/editInsiders",
// 删除管理系统用户
deleteInsiders: "/accountManager/deleteInsiders",
// 管理系统导出系统用户
downloadInsiders: "/accountManager/downloadInsiders",
// 注册B端用户单位
addOrganization: "/accountManager/addOrganization",
@@ -85,11 +97,15 @@ export default {
editOrganization: "/accountManager/editOrganization",
// 删除B端用户单位
deleteOrganization: "/accountManager/deleteOrganization",
// 管理系统导出B端用户单位
downloadOrganization: "/accountManager/downloadOrganization",
// 查看监控记录
showMonitoring: "/accountManager/showMonitoring",
// 删除监控记录
deleteMonitoring: "/accountManager/deleteMonitoring",
// 管理系统导出监控记录
downloadMonitoring: "/accountManager/downloadMonitoring",
// 管理系统检索竞赛 uid
searchContestUid: "/accountManager/searchContestUid",
@@ -101,6 +117,8 @@ export default {
editContest: "/accountManager/editContest",
// 管理系统删除竞赛信息
delContest: "/accountManager/delContest",
// 管理系统导出竞赛信息
downloadContest: "/accountManager/downloadContest",
// 管理系统导入选择题
importChoiceTopic: "/accountManager/importChoiceTopic",
@@ -112,6 +130,8 @@ export default {
editChoiceTopic: "/accountManager/editChoiceTopic",
// 管理系统删除选择题
delChoiceTopic: "/accountManager/delChoiceTopic",
// 管理系统导出选择题
downloadChoiceTopic: "/accountManager/downloadChoiceTopic",
// 管理系统导入竞赛账号信息
importAccount: "/accountManager/importAccount",
@@ -123,6 +143,8 @@ export default {
editAccount: "/accountManager/editAccount",
// 管理系统删除竞赛账号信息
delAccount: "/accountManager/delAccount",
// 管理系统导出竞赛账号信息
downloadAccount: "/accountManager/downloadAccount",
// 管理系统重置竞赛账号密码
resetAccount: "/accountManager/resetAccount",
@@ -144,11 +166,15 @@ export default {
editSN: "/accountManager/editSN",
// 删除SN号
deleteSN: "/accountManager/deleteSN",
// 管理系统导出SN号
downloadSN: "/accountManager/downloadSN",
// 查看SN号绑定记录
showBindSNRecord: "/accountManager/showBindSNRecord",
// 删除SN号绑定记录
deleteBindSNRecord: "/accountManager/deleteBindSNRecord",
// 管理系统导出SN号绑定记录
downloadBindSNRecord: "/accountManager/downloadBindSNRecord",
// 搜索可分配的SN号
searchAllocationSN: "/accountManager/searchAllocationSN",
@@ -160,4 +186,25 @@ export default {
showAllocationSNRecord: "/accountManager/showAllocationSNRecord",
// 删除B端SN号分配记录
deleteAllocationSNRecord: "/accountManager/deleteAllocationSNRecord",
// 管理系统导出B端SN号分配记录
downloadAllocationSN: "/accountManager/downloadAllocationSN",
// 查看未知北斗卡消息
showUnknownBDCard: "/accountManager/showUnknownBDCard",
// 删除未知北斗卡消息
deleteUnknownBDCard: "/accountManager/deleteUnknownBDCard",
// 管理系统导出未知北斗卡消息
downloadUnknownBDCard: "/accountManager/downloadUnknownBDCard",
// 查看未知SN号消息
showUnknownSN: "/accountManager/showUnknownSN",
// 删除未知SN号消息
deleteUnknownSN: "/accountManager/deleteUnknownSN",
// 管理系统导出未知SN号消息
downloadUnknownSNRecord: "/accountManager/downloadUnknownSNRecord",
// 获取SN号竞赛消息
getSNContestMsg: "/accountManager/getSNContestMsg",
// 管理系统导出SN号竞赛消息
downloadSNConest: "/accountManager/downloadSNConest",
}

View File

@@ -132,7 +132,7 @@ const confirm = () => {
const addSN = (requestMsg) => {
requestMsg.forEach((element) => {
element.sn_number = encrypt(String(element.sn_number));
element.sn_number = encrypt(String(element.sn_number).padStart(8, '0'));
});
const data = { requestMsg };
$http.post($url.addSN, data).then((res) => {

View File

@@ -53,7 +53,7 @@ const createForm = () => {
let difference = Math.abs(singleFormNum.value - input.value.length);
for (let i = 0; i < difference; i++) {
if (singleFormNum.value > input.value.length) {
input.value.push({ label: `卡${input.value.length + 1}` });
input.value.push({ label: `SN号${input.value.length + 1}` });
} else if (singleFormNum.value < input.value.length) {
input.value.pop();
}

View File

@@ -12,7 +12,7 @@
<el-form-item class="mx-1 font-bold" label="SN号" prop="sn_number">
<el-input
clearable
placeholder="请输入卡号"
placeholder="请输入SN号"
minlength="8"
maxlength="8"
v-model="ruleForm.sn_number"
@@ -44,7 +44,7 @@ const checkLength = (length) => {
const rules = reactive({
sn_number: [
{ required: true, message: "请输入卡号", trigger: "blur" },
{ required: true, message: "请输入SN号", trigger: "blur" },
{ validator: checkLength(8), trigger: "blur" },
]
});

View File

@@ -33,7 +33,7 @@ import SingleAdd from "./singleAdd.vue";
const singleFormNum = ref(1);
const checked = ref(true);
const input = ref([{ label: "卡1" }]);
const input = ref([{ label: "账号1" }]);
const singleAddRef = ref(null);
const formClone = ref([]);
@@ -61,7 +61,7 @@ const createForm = () => {
let difference = Math.abs(singleFormNum.value - input.value.length);
for (let i = 0; i < difference; i++) {
if (singleFormNum.value > input.value.length) {
input.value.push({ label: `卡${input.value.length + 1}` });
input.value.push({ label: `账号${input.value.length + 1}` });
} else if (singleFormNum.value < input.value.length) {
input.value.pop();
}

View File

@@ -38,7 +38,7 @@ import SingleAdd from "./singleAdd.vue";
const singleFormNum = ref(1);
const checked = ref(true);
const input = ref([{ label: "卡1" }]);
const input = ref([{ label: "业务1" }]);
const singleAddRef = ref(null);
const formClone = ref([]);
@@ -68,7 +68,7 @@ const createForm = () => {
let difference = Math.abs(singleFormNum.value - input.value.length);
for (let i = 0; i < difference; i++) {
if (singleFormNum.value > input.value.length) {
input.value.push({ label: `卡${input.value.length + 1}` });
input.value.push({ label: `业务${input.value.length + 1}` });
} else if (singleFormNum.value < input.value.length) {
input.value.pop();
}

View File

@@ -33,7 +33,7 @@ import SingleAdd from "./singleAdd.vue";
const singleFormNum = ref(1);
const checked = ref(true);
const input = ref([{ label: "卡1" }]);
const input = ref([{ label: "账号1" }]);
const singleAddRef = ref(null);
const formClone = ref([]);
@@ -53,7 +53,7 @@ const createForm = () => {
let difference = Math.abs(singleFormNum.value - input.value.length);
for (let i = 0; i < difference; i++) {
if (singleFormNum.value > input.value.length) {
input.value.push({ label: `卡${input.value.length + 1}` });
input.value.push({ label: `账号${input.value.length + 1}` });
} else if (singleFormNum.value < input.value.length) {
input.value.pop();
}

View File

@@ -33,7 +33,7 @@ import SingleAdd from "./singleAdd.vue";
const singleFormNum = ref(1);
const checked = ref(true);
const input = ref([{ label: "卡1" }]);
const input = ref([{ label: "题目1" }]);
const singleAddRef = ref(null);
const formClone = ref([]);
@@ -53,7 +53,7 @@ const createForm = () => {
let difference = Math.abs(singleFormNum.value - input.value.length);
for (let i = 0; i < difference; i++) {
if (singleFormNum.value > input.value.length) {
input.value.push({ label: `卡${input.value.length + 1}` });
input.value.push({ label: `题目${input.value.length + 1}` });
} else if (singleFormNum.value < input.value.length) {
input.value.pop();
}

View File

@@ -33,7 +33,7 @@ import SingleAdd from "./singleAdd.vue";
const singleFormNum = ref(1);
const checked = ref(true);
const input = ref([{ label: "卡1" }]);
const input = ref([{ label: "竞赛1" }]);
const singleAddRef = ref(null);
const formClone = ref([]);
@@ -54,7 +54,7 @@ const createForm = () => {
let difference = Math.abs(singleFormNum.value - input.value.length);
for (let i = 0; i < difference; i++) {
if (singleFormNum.value > input.value.length) {
input.value.push({ label: `卡${input.value.length + 1}` });
input.value.push({ label: `竞赛${input.value.length + 1}` });
} else if (singleFormNum.value < input.value.length) {
input.value.pop();
}

View File

@@ -0,0 +1,82 @@
<template>
<UploadFile
ref="uploadFileRef"
:options="options"
:relatedRules="relatedRules"
:relatedOptions="relatedOptions"
/>
</template>
<script setup>
import { ref } from "vue";
import { ElMessage } from "element-plus";
import UploadFile from "../../../operate/uploadFile.vue";
const uploadFileRef = ref(null);
const formClone = ref([]);
const options = {
limit: 1,
accept: ".xlsx",
action: "",
multiple: false,
listType: "text",
autoUpload: false,
};
const relatedRules = {
SN: {
value: "",
label: "比赛SN号",
},
};
const relatedOptions = [
{
value: "0",
label: "比赛SN号",
disabled: false,
},
];
const emit = defineEmits(["addContest"]);
const resetCheckForm = () => {
if (!uploadFileRef) return;
uploadFileRef.value.handleExceed();
};
const confirm = async () => {
if (!uploadFileRef) return;
formClone.value = [];
const length = uploadFileRef.value.loadData.length;
if (length == 0) return ElMessage.error("请先上传文件!");
const flag = await uploadFileRef.value.confirm();
if (!flag) return ElMessage.error("请先选择表格关联项!");
ElMessage({
message: `正在上传数据中,请稍等...`,
type: "success",
});
setTimeout(() => {
uploadFileRef.value.loadData.forEach((ExcleForm) => {
ExcleForm.forEach((worksheet) => {
let context = [...worksheet];
context.shift();
context.forEach((item) => {
if (item.length != 0) {
formClone.value.push({
SN: item[relatedRules.SN.value],
});
}
});
});
});
emit("addContest", formClone.value);
}, 3000);
};
defineExpose({ resetCheckForm, confirm, formClone });
</script>
<style scoped></style>

View File

@@ -0,0 +1,113 @@
<template>
<div>
<div
style="font-size: 2rem"
class="flex flex-warp justify-center items-center font-bold"
>
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
<div v-if="checkNeed">&nbsp;&nbsp;</div>
<el-checkbox
v-if="checkNeed"
v-model="checked"
label="为所有表单进行相同操作"
size="large"
/>
</div>
<el-scrollbar max-height="40rem">
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
{{ item.label }}
</div>
<SingleAdd ref="singleAddRef" />
</div>
</el-scrollbar>
</div>
</template>
<script setup>
import { ref, watch } from "vue";
import { ElMessage } from "element-plus";
import SingleAdd from "./singleAdd.vue";
const singleFormNum = ref(1);
const checked = ref(true);
const input = ref([{ label: "比赛SN号1" }]);
const singleAddRef = ref(null);
const formClone = ref([]);
const props = defineProps({
checkNeed: Boolean,
});
const emit = defineEmits(["addContest"]);
const initData = () => {
setTimeout(() => {
singleAddRef.value.forEach((item) => {});
}, 0);
};
const createForm = () => {
let difference = Math.abs(singleFormNum.value - input.value.length);
for (let i = 0; i < difference; i++) {
if (singleFormNum.value > input.value.length) {
input.value.push({ label: `比赛SN号${input.value.length + 1}` });
} else if (singleFormNum.value < input.value.length) {
input.value.pop();
}
}
if (checked.value) {
initData();
}
};
const resetCheckForm = () => {
if (!singleAddRef) return;
singleAddRef.value.forEach((element) => {
element.resetCheckForm();
});
singleFormNum.value = 1;
createForm();
};
const confirm = () => {
if (!singleAddRef) return;
let valid = true;
formClone.value = [];
singleAddRef.value.forEach((element) => {
element.validate().then((result) => {
if (result) {
formClone.value.push({ ...element.ruleForm });
} else {
valid = result;
}
});
});
setTimeout(() => {
if (valid) {
emit("addContest", formClone.value);
singleAddRef.value.forEach((item) => {
item.resetCheckForm();
});
ElMessage({
message: `提交成功!`,
type: "success",
});
} else {
ElMessage.error("提交失败!");
}
}, 0);
};
defineExpose({ resetCheckForm, confirm, formClone });
watch(checked, (value) => {
if (value) {
initData();
}
});
</script>
<style scoped></style>

View File

@@ -0,0 +1,88 @@
<template>
<el-form
ref="ruleFormRef"
style="max-width: 600px"
:model="ruleForm"
:rules="rules"
label-width="auto"
size="default"
status-icon
class="mx-auto"
>
<el-form-item class="mx-1 font-bold" label="比赛SN号" prop="SN">
<el-input
clearable
placeholder="请输入比赛SN号"
minlength="8"
maxlength="8"
v-model="ruleForm.SN"
@input="filter(ruleForm.SN, 'SN')"
/>
</el-form-item>
</el-form>
</template>
<script setup>
import { ref, reactive } from "vue";
import { ElMessage } from "element-plus";
const ruleFormRef = ref(null);
const ruleForm = reactive({
SN: "",
});
const formClone = ref({});
const rules = reactive({
SN: [
{ required: true, message: "请输入比赛SN号", trigger: "blur" },
{ validator: checkLength(8), trigger: "blur" }
]
});
const emit = defineEmits(["addContest"]);
const filter = (value, label) => {
if (/[=\s"'+-]/.test(value)) {
if (ruleForm[label]) {
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
}
}
};
const resetCheckForm = () => {
if (!ruleFormRef) return;
ruleFormRef.value.resetFields();
};
const confirm = async () => {
if (!ruleFormRef) return;
await ruleFormRef.value.validate((valid) => {
if (valid) {
formClone.value = { ...ruleForm };
emit("addContest", [formClone.value]);
ruleFormRef.value.resetFields();
ElMessage({
message: `提交成功!`,
type: "success",
});
} else {
ElMessage.error("提交失败!");
}
});
};
const validate = () => {
if (!ruleFormRef) return Promise.resolve(false);
return new Promise((resolve) => {
ruleFormRef.value.validate((valid) => {
resolve(valid);
});
});
};
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
</script>
<style scoped></style>

View File

@@ -0,0 +1,206 @@
<template>
<el-dialog
v-model="dialogVisible"
:show-close="false"
style="width: 80%"
center
align-center
:before-close="resetCheckForm"
>
<template #header="{ titleId, titleClass }">
<div
style="font-size: 2rem"
class="w-full font-bold"
:id="titleId"
:class="titleClass"
>
{{ title }}
</div>
<div
@click="resetCheckForm"
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
>
<el-icon>
<CloseBold />
</el-icon>
</div>
</template>
<FormTools @showTools="showTools" :dialogObj="contestMsgActive" />
<el-form
ref="ruleFormRef"
style="max-width: 600px"
:model="ruleForm"
:rules="rules"
label-width="auto"
size="default"
status-icon
class="mx-auto"
>
<el-form-item label="比赛起止时间">
<el-col :span="11">
<el-form-item prop="contest_start">
<el-date-picker
v-model="ruleForm.contest_start"
type="datetime"
placeholder="请选择比赛开始时间"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="2" class="text-center">
<span class="text-gray-500">-</span>
</el-col>
<el-col :span="11">
<el-form-item prop="contest_end">
<el-date-picker
v-model="ruleForm.contest_end"
type="datetime"
placeholder="请选择比赛结束时间"
style="width: 100%"
/>
</el-form-item>
</el-col>
</el-form-item>
</el-form>
<SingleAdd ref="singleAddRef" v-if="dialogSingleVisible" @addContest="addContest" />
<MultipleAdd
ref="multipleAddRef"
v-if="dialogMultipleVisible"
:checkNeed="false"
@addContest="addContest"
/>
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addContest="addContest" />
<template #footer>
<div class="dialog-footer">
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
<el-button style="font-weight: bold" type="primary" @click="confirm">
确定
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, reactive } from "vue";
import { CloseBold } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import FormTools from "../../../operate/formTools.vue";
import SingleAdd from "./singleAdd.vue";
import MultipleAdd from "./multipleAdd.vue";
import ExcleAdd from "./excleAdd.vue";
import contestActiveStore from "../../../../stores/contest/contest";
const contestMsgActive = contestActiveStore();
const dialogVisible = ref(false);
const singleAddRef = ref(null);
const multipleAddRef = ref(null);
const excleAddRef = ref(null);
const dialogSingleVisible = ref(true);
const dialogMultipleVisible = ref(false);
const dialogExcleVisible = ref(false);
const ruleFormRef = ref(null);
const ruleForm = reactive({
contest_start: "",
contest_end: "",
});
const formClone = ref({});
const rules = reactive({
contest_start: [
{ type: "date", required: true, message: "竞赛开始时间", trigger: "change" },
],
contest_end: [
{ type: "date", required: true, message: "竞赛结束时间", trigger: "change" },
],
});
const props = defineProps({
title: String,
});
const emit = defineEmits(["reloadData"]);
const showTools = (operateType) => {
switch (operateType) {
case "single":
dialogSingleVisible.value = true;
dialogMultipleVisible.value = false;
dialogExcleVisible.value = false;
contestMsgActive.dialogSingleVisible = dialogSingleVisible.value;
contestMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
contestMsgActive.dialogExcleVisible = dialogExcleVisible.value;
break;
case "multiple":
dialogSingleVisible.value = false;
dialogMultipleVisible.value = true;
dialogExcleVisible.value = false;
contestMsgActive.dialogSingleVisible = dialogSingleVisible.value;
contestMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
contestMsgActive.dialogExcleVisible = dialogExcleVisible.value;
break;
case "excle":
dialogSingleVisible.value = false;
dialogMultipleVisible.value = false;
dialogExcleVisible.value = true;
contestMsgActive.dialogSingleVisible = dialogSingleVisible.value;
contestMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
contestMsgActive.dialogExcleVisible = dialogExcleVisible.value;
break;
default:
break;
}
};
const resetCheckForm = () => {
if (dialogSingleVisible.value) {
singleAddRef.value.resetCheckForm();
} else if (dialogMultipleVisible.value) {
multipleAddRef.value.resetCheckForm();
} else if (dialogExcleVisible.value) {
excleAddRef.value.resetCheckForm();
}
dialogVisible.value = false;
};
const confirm = async () => {
if (!ruleFormRef) return;
await ruleFormRef.value.validate((valid) => {
if (valid) {
formClone.value = { ...ruleForm };
if (dialogSingleVisible.value) {
singleAddRef.value.confirm();
} else if (dialogMultipleVisible.value) {
multipleAddRef.value.confirm();
} else if (dialogExcleVisible.value) {
excleAddRef.value.confirm();
}
ElMessage({
message: `提交成功!`,
type: "success",
});
} else {
ElMessage.error("提交失败!");
}
});
};
const addContest = (requestMsg) => {
const SNArr = [];
requestMsg.forEach((element) => {
SNArr.push(element.SN);
});
emit("reloadData", { SNArr, time_at: formClone.value });
resetCheckForm();
};
defineExpose({ dialogVisible });
</script>
<style scoped></style>

View File

@@ -33,7 +33,7 @@ import SingleAdd from "./singleAdd.vue";
const singleFormNum = ref(1);
const checked = ref(true);
const input = ref([{ label: "卡1" }]);
const input = ref([{ label: "账号1" }]);
const singleAddRef = ref(null);
const formClone = ref([]);
@@ -56,7 +56,7 @@ const createForm = () => {
let difference = Math.abs(singleFormNum.value - input.value.length);
for (let i = 0; i < difference; i++) {
if (singleFormNum.value > input.value.length) {
input.value.push({ label: `卡${input.value.length + 1}` });
input.value.push({ label: `账号${input.value.length + 1}` });
} else if (singleFormNum.value < input.value.length) {
input.value.pop();
}

View File

@@ -30,7 +30,7 @@ import SingleAdd from "./singleAdd.vue";
const singleFormNum = ref(1);
const checked = ref(true);
const input = ref([{ label: "卡1" }]);
const input = ref([{ label: "单位1" }]);
const singleAddRef = ref(null);
const formClone = ref([]);
@@ -51,7 +51,7 @@ const createForm = () => {
let difference = Math.abs(singleFormNum.value - input.value.length);
for (let i = 0; i < difference; i++) {
if (singleFormNum.value > input.value.length) {
input.value.push({ label: `卡${input.value.length + 1}` });
input.value.push({ label: `单位${input.value.length + 1}` });
} else if (singleFormNum.value < input.value.length) {
input.value.pop();
}

View File

@@ -206,6 +206,11 @@
operateLabel="删除SN号"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出SN号数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -215,6 +220,7 @@ import { ElMessage } from "element-plus";
import TabelTools from "../operate/tabelTools.vue";
import AddNewData from "../operate/addNewData.vue";
import DownloadData from "../operate/downloadData.vue";
import TabelSelect from "../operate/tabelSelect.vue";
import SearchKey from "../search/searchKey.vue";
import SortSearch from "../search/sortSearch.vue";
@@ -235,6 +241,7 @@ import $url from "../../api/url";
import { encrypt } from "../../utils/aes";
import { judgment } from "../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../utils/downloadData.js";
const SNActive = SNActiveStore();
@@ -262,6 +269,7 @@ const createdSortDateTimeRef = ref(null);
const updatedSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const addSNFormRef = ref(null);
const downloadDataRef = ref(null);
const editSNFormRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
@@ -355,6 +363,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
SNActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -523,6 +534,65 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"SN号",
"绑定状态",
"绑定用户",
"注册时间",
"绑定状态变更时间"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadSN, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ SNMsg });
watch(searchOptions, (value) => {

View File

@@ -26,7 +26,8 @@
:key="sn"
type="info"
class="sn-tag"
effect="dark"
:effect="mode ? 'dark' : SNArr.includes(sn) ? 'dark' : 'plain'"
@click="unLoadSN(sn)"
>
{{ sn }}
</el-tag>
@@ -52,9 +53,18 @@
@change="validateSNCount"
/>
</div>
<el-button class="bind-button" type="primary" @click="allocationSN"
>确认绑定</el-button
<el-button class="bind-button" type="primary" @click="allocationSN">
确认{{ mode ? "绑定" : "解绑" }}
</el-button>
<el-button
class="bind-button"
style="margin-left: 0px"
type="primary"
v-model="mode"
@click="switchMode"
>
{{ mode ? "解绑" : "绑定" }}管理
</el-button>
</div>
</div>
</div>
@@ -62,12 +72,12 @@
<el-card class="box-card">
<template #header>
<div class="card-header">
<span>未绑定的用户</span>
<span>{{ mode ? "可" : "已" }}绑定的用户</span>
</div>
</template>
<div class="unbind-users">
<el-tag
v-for="user in unbindUsers"
v-for="user in usersArr"
:key="user"
type="info"
class="user-tag"
@@ -81,12 +91,12 @@
<el-card class="box-card">
<template #header>
<div class="card-header">
<span>未绑定的SN号</span>
<span>{{ mode ? "可绑定" : "要解绑" }}的SN号</span>
</div>
</template>
<div class="unbind-sn">
<el-tag
v-for="sn in unbindSN"
v-for="sn in SNArr"
:key="sn"
type="info"
class="sn-tag"
@@ -115,27 +125,46 @@ const SNAdminActive = SNAdminActiveStore();
const selectedUser = ref("");
const selectedSNs = ref([]);
const snCount = ref(0);
const unbindUsers = ref([]);
const mode = ref(true);
const usersArr = ref([]);
const userObj = ref({});
const unbindSN = ref([]);
const SNArr = ref([]);
const contentBlockRef = ref(null);
const contentBlockHeight = ref(0);
const selectUser = (user) => {
selectedSNs.value = [];
selectedUser.value = user;
SNAdminActive.selectedUser = user;
snCount.value = userObj.value[user].length;
const sn_set = userObj.value[user].sn_set.split(",");
if (userObj.value[user].sn_set !== "" && sn_set.length !== 0) {
selectedSNs.value.push(...sn_set);
}
};
const toggleSelectSN = (sn) => {
if (selectedSNs.value.includes(sn)) {
selectedSNs.value = selectedSNs.value.filter((s) => s !== sn);
SNAdminActive.selectedSNs = selectedSNs.value.filter((s) => s !== sn);
} else {
if (selectedSNs.value.length < snCount.value) {
if (mode.value) {
if (selectedSNs.value.includes(sn)) {
selectedSNs.value = selectedSNs.value.filter((s) => s !== sn);
SNAdminActive.selectedSNs = selectedSNs.value.filter((s) => s !== sn);
} else if (selectedSNs.value.length < snCount.value) {
selectedSNs.value.push(sn);
} else {
ElMessage.warning("已达到可绑定的SN号数量上限!");
}
} else {
SNArr.value = SNArr.value.filter((s) => s !== sn);
}
};
const unLoadSN = (sn) => {
if (!mode.value) {
if (SNArr.value.includes(sn)) {
SNArr.value = SNArr.value.filter((s) => s !== sn);
} else {
SNArr.value.push(sn);
}
}
};
@@ -143,11 +172,12 @@ const validateSNCount = () => {
if (snCount.value < 0) {
snCount.value = 0;
ElMessage.warning("SN号数量不能为负数!");
} else {
if (selectedSNs.value.length > snCount.value) {
snCount.value = selectedSNs.value.length;
ElMessage.warning("已达到可绑定的SN号数量上限!");
}
} else if (mode.value && selectedSNs.value.length > snCount.value) {
snCount.value = selectedSNs.value.length;
ElMessage.warning("已达到可绑定的SN号数量上限!");
} else if (!mode.value && selectedSNs.value.length > snCount.value) {
snCount.value = Math.abs(selectedSNs.value.length - SNArr.value.length);
ElMessage.warning("已达到可绑定的SN号数量上限!");
}
SNAdminActive.snCount = snCount.value;
};
@@ -162,14 +192,21 @@ const resetCheckForm = () => {
};
const searchAllocationUser = () => {
$http.get($url.searchAllocationUser).then((res) => {
const data = {
mode: mode.value,
};
$http.post($url.searchAllocationUser, data).then((res) => {
if (res.data.code === 200) {
res.data.userArr.forEach(element => {
unbindUsers.value.push(element.account_name);
userObj.value[element.account_name] = element.uid;
res.data.userArr.forEach((element) => {
usersArr.value.push(element.account_name);
userObj.value[element.account_name] = {
uid: element.uid,
length: element.length,
sn_set: element.sn_set,
};
});
} else {
unbindUsers.value = [];
usersArr.value = [];
resetCheckForm();
// ElMessage.error("未查找到相关数据!");
}
@@ -177,13 +214,13 @@ const searchAllocationUser = () => {
};
const searchAllocationSN = () => {
$http.get($url.searchAllocationSN).then((res) => {
$http.post($url.searchAllocationSN).then((res) => {
if (res.data.code === 200) {
res.data.snArr.forEach(element => {
unbindSN.value.push(element.sn_number);
res.data.snArr.forEach((element) => {
SNArr.value.push(element.sn_number);
});
} else {
unbindSN.value = [];
SNArr.value = [];
resetCheckForm();
// ElMessage.error("未查找到相关数据!");
}
@@ -191,32 +228,49 @@ const searchAllocationSN = () => {
};
const allocationSN = () => {
if (selectedUser.value === "" || selectedSNs.value.length === 0) {
if (
selectedUser.value === "" ||
(mode.value && selectedSNs.value.length === 0) ||
(!mode.value && SNArr.value.length === 0)
) {
ElMessage.warning("请选择用户和SN号!");
return;
}
const data = {
user_uid: userObj.value[selectedUser.value],
user_uid: userObj.value[selectedUser.value].uid,
length: snCount.value,
sn_set: selectedSNs.value.join(","),
sn_set: mode.value
? selectedSNs.value.join(",")
: selectedSNs.value.filter((s) => !SNArr.value.includes(s)).join(","),
};
$http.post($url.allocationSN, data).then((res) => {
if (res.data.code === 200) {
resetCheckForm();
unbindUsers.value = [];
unbindSN.value = [];
usersArr.value = [];
SNArr.value = [];
searchAllocationUser();
searchAllocationSN();
ElMessage({
message: "绑定成功!",
message: mode.value ? "绑定成功!" : "解绑成功!",
type: "success",
});
} else {
ElMessage.error("绑定失败!");
ElMessage.error(mode.value ? "绑定失败!" : "解绑失败!");
}
});
};
const switchMode = () => {
mode.value = !mode.value;
usersArr.value = [];
SNArr.value = [];
resetCheckForm();
searchAllocationUser();
if (mode.value) {
searchAllocationSN();
}
};
const setContentBlockHeight = async () => {
await nextTick();
if (contentBlockRef.value) {

View File

@@ -141,6 +141,11 @@
operateLabel="删除SN号分配记录"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出SN号分配记录数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -154,6 +159,7 @@ import SearchKey from "../search/searchKey.vue";
import Pagination from "../search/pagination.vue";
import DataShow from "../operate/dataShow.vue";
import PasswordOauth from "../operate/passwordOauth.vue";
import DownloadData from "../operate/downloadData.vue";
import allocationSNRecordActiveStore from "../../stores/allocationSNRecord";
@@ -163,6 +169,7 @@ import $url from "../../api/url";
import { encrypt } from "../../utils/aes";
import { judgment } from "../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../utils/downloadData.js";
const allocationSNRecordActive = allocationSNRecordActiveStore();
@@ -179,6 +186,7 @@ const SearchLengthKeyRef = ref(null);
const SearchSNKeyRef = ref(null);
const PaginationRef = ref(null);
const DataShowRef = ref(null);
const downloadDataRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
const dialogSortVisible = ref(false);
@@ -218,6 +226,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
allocationSNRecordActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -331,6 +342,64 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"账户名",
"账户uid",
"可管理的SN号数量",
"SN号"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadAllocationSNRecord, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ bindSNRecordMsg });
watch(searchOptions, (value) => {

View File

@@ -243,6 +243,11 @@
operateLabel="删除北斗卡"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出北斗卡数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -252,6 +257,7 @@ import { ElMessage } from "element-plus";
import TabelTools from "../operate/tabelTools.vue";
import AddNewData from "../operate/addNewData.vue";
import DownloadData from "../operate/downloadData.vue";
import TabelSelect from "../operate/tabelSelect.vue";
import SearchKey from "../search/searchKey.vue";
import SortSearch from "../search/sortSearch.vue";
@@ -272,6 +278,7 @@ import $url from "../../api/url";
import { encrypt } from "../../utils/aes";
import { judgment } from "../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../utils/downloadData.js";
const bdCardMsgActive = bdCardActiveStore();
@@ -303,6 +310,7 @@ const createdSortDateTimeRef = ref(null);
const updatedSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const addBdCardFormRef = ref(null);
const downloadDataRef = ref(null);
const editBdCardFormRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
@@ -417,6 +425,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
bdCardMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -588,6 +599,67 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"卡号",
"IMSI号",
"白名单类型",
"绑定状态",
"绑定用户",
"注册时间",
"绑定状态变更时间"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadBDCard, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ bdCardMsg });
watch(searchOptions, (value) => {

View File

@@ -180,6 +180,11 @@
operateLabel="删除北斗卡绑定记录"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出北斗卡绑定记录数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -195,6 +200,7 @@ import SelectSearch from "../search/selectSearch.vue";
import DateTimePicker from "../search/dateTimePicker.vue";
import Pagination from "../search/pagination.vue";
import PasswordOauth from "../operate/passwordOauth.vue";
import DownloadData from "../operate/downloadData.vue";
import bindRecordActiveStore from "../../stores/bindRecord";
@@ -206,6 +212,7 @@ import $url from "../../api/url";
import { encrypt } from "../../utils/aes";
import { judgment } from "../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../utils/downloadData.js";
const bindRecordMsgActive = bindRecordActiveStore();
@@ -224,6 +231,7 @@ const SelectTypeSearchRef = ref(null);
const createdDateTimePickerRef = ref(null);
const createdSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const downloadDataRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
const dialogSortVisible = ref(false);
@@ -306,6 +314,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
bindRecordMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -451,6 +462,66 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"账户名",
"用户类型",
"账户uid",
"卡号",
"操作类型",
"记录时间"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadBindRecord, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ bindRecordMsg });
watch(searchOptions, (value) => {

View File

@@ -180,6 +180,11 @@
operateLabel="删除SN号绑定记录"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出SN号绑定记录数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -195,6 +200,7 @@ import SelectSearch from "../search/selectSearch.vue";
import DateTimePicker from "../search/dateTimePicker.vue";
import Pagination from "../search/pagination.vue";
import PasswordOauth from "../operate/passwordOauth.vue";
import DownloadData from "../operate/downloadData.vue";
import bindSNRecordActiveStore from "../../stores/bindSNRecord";
@@ -206,6 +212,7 @@ import $url from "../../api/url";
import { encrypt } from "../../utils/aes";
import { judgment } from "../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../utils/downloadData.js";
const bindSNRecordMsgActive = bindSNRecordActiveStore();
@@ -224,6 +231,7 @@ const SelectTypeSearchRef = ref(null);
const createdDateTimePickerRef = ref(null);
const createdSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const downloadDataRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
const dialogSortVisible = ref(false);
@@ -309,6 +317,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
bindSNRecordMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -454,6 +465,66 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"账户名",
"用户类型",
"账户uid",
"SN号",
"操作类型",
"记录时间"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadBindSNRecord, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ bindSNRecordMsg });
watch(searchOptions, (value) => {

View File

@@ -325,6 +325,11 @@
operateLabel="删除B端用户"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出B端用户数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -334,6 +339,7 @@ import { ElMessage } from "element-plus";
import TabelTools from "../operate/tabelTools.vue";
import AddNewData from "../operate/addNewData.vue";
import DownloadData from "../operate/downloadData.vue";
import TabelSelect from "../operate/tabelSelect.vue";
import SearchKey from "../search/searchKey.vue";
import SortSearch from "../search/sortSearch.vue";
@@ -354,6 +360,7 @@ import $url from "../../api/url";
import { encrypt } from "../../utils/aes";
import { judgment } from "../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../utils/downloadData.js";
const bsideMsgActive = bsideActiveStore();
@@ -388,6 +395,7 @@ const updatedSortDateTimeRef = ref(null);
const loginSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const addBsideFormRef = ref(null);
const downloadDataRef = ref(null);
const editBsideFormRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
@@ -506,6 +514,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
bsideMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -742,6 +753,71 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"账号状态",
"账号角色",
"账号名称",
"单位名称",
"用户姓名",
"手机号码",
"基本信息",
"注册时间",
"账号状态变更时间",
"上次登录时间",
"登录状态"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadBside, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ bsideMsg });
watch(searchOptions, (value) => {

View File

@@ -335,6 +335,11 @@
operateLabel="删除公司业务"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出公司业务数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -344,6 +349,7 @@ import { ElMessage } from "element-plus";
import TabelTools from "../operate/tabelTools.vue";
import AddNewData from "../operate/addNewData.vue";
import DownloadData from "../operate/downloadData.vue";
import TabelSelect from "../operate/tabelSelect.vue";
import SearchKey from "../search/searchKey.vue";
import SortSearch from "../search/sortSearch.vue";
@@ -364,6 +370,7 @@ import $url from "../../api/url";
import { encrypt } from "../../utils/aes";
import { judgment } from "../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../utils/downloadData.js";
const businessMsgActive = businessActiveStore();
@@ -397,6 +404,7 @@ const createdSortDateTimeRef = ref(null);
const updatedSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const addBusinessFormRef = ref(null);
const downloadDataRef = ref(null);
const editBusinessFormRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
@@ -528,6 +536,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
businessMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -749,6 +760,72 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"随机盐值",
"业务登录网址",
"业务网址",
"业务临时标识",
"业务ID",
"业务密钥",
"业务名称",
"业务类型",
"业务等级",
"业务状态",
"业务开通时间",
"业务变更时间"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadBusiness, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ businessMsg });
watch(searchOptions, (value) => {

View File

@@ -231,6 +231,11 @@
operateLabel="重置账号密码"
@requestOperate="resetAccount"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出账号数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -240,6 +245,7 @@ import { ElMessage } from "element-plus";
import TabelTools from "../../operate/tabelTools.vue";
import AddNewData from "../../operate/addNewData.vue";
import DownloadData from "../../operate/downloadData.vue";
import TabelSelect from "../../operate/tabelSelect.vue";
import SearchKey from "../../search/searchKey.vue";
import SortSearch from "../../search/sortSearch.vue";
@@ -260,6 +266,7 @@ import $url from "../../../api/url";
import { encrypt } from "../../../utils/aes";
import { judgment } from "../../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../../utils/downloadData.js";
const accountMsgActive = accountActiveStore();
@@ -287,6 +294,7 @@ const SelectLoginStatusSearchRef = ref(null);
const createdSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const addAccountFormRef = ref(null);
const downloadDataRef = ref(null);
const editAccountFormRef = ref(null);
const delPasswordOauthRef = ref(null);
const resetPasswordOauthRef = ref(null);
@@ -394,6 +402,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
accountMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -586,6 +597,66 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"账号uid",
"竞赛uid",
"账号名称",
"账号状态",
"注册时间",
"登录状态"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadAccount, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ accountMsg });
watch(searchOptions, (value) => {

View File

@@ -200,6 +200,11 @@
operateLabel="删除单选题"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出题目数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -209,6 +214,7 @@ import { ElMessage } from "element-plus";
import TabelTools from "../../operate/tabelTools.vue";
import AddNewData from "../../operate/addNewData.vue";
import DownloadData from "../../operate/downloadData.vue";
import TabelSelect from "../../operate/tabelSelect.vue";
import SearchKey from "../../search/searchKey.vue";
import Pagination from "../../search/pagination.vue";
@@ -226,6 +232,7 @@ import $url from "../../../api/url";
import { encrypt } from "../../../utils/aes";
import { judgment } from "../../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../../utils/downloadData.js";
const choiceTopicMsgActive = choiceTopicActiveStore();
@@ -252,6 +259,7 @@ const SearchOptionsDKeyRef = ref(null);
const SearchAnswerKeyRef = ref(null);
const PaginationRef = ref(null);
const addChoiceTopicFormRef = ref(null);
const downloadDataRef = ref(null);
const editChoiceTopicFormRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
@@ -314,6 +322,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
choiceTopicMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -481,6 +492,66 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"题目",
"选项A",
"选项B",
"选项C",
"选项D",
"答案"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadChoiceTopic, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ choiceTopicMsg });
watch(searchOptions, (value) => {

View File

@@ -380,6 +380,11 @@
operateLabel="删除竞赛"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出竞赛数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -389,6 +394,7 @@ import { ElMessage } from "element-plus";
import TabelTools from "../../operate/tabelTools.vue";
import AddNewData from "../../operate/addNewData.vue";
import DownloadData from "../../operate/downloadData.vue";
import TabelSelect from "../../operate/tabelSelect.vue";
import SearchKey from "../../search/searchKey.vue";
import SortSearch from "../../search/sortSearch.vue";
@@ -409,6 +415,7 @@ import $url from "../../../api/url";
import { encrypt } from "../../../utils/aes";
import { judgment } from "../../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../../utils/downloadData.js";
const contestMsgActive = contestActiveStore();
@@ -449,6 +456,7 @@ const contestEndSortDateTimeRef = ref(null);
const createdSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const addContestFormRef = ref(null);
const downloadDataRef = ref(null);
const editContestFormRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
@@ -571,6 +579,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
contestMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -829,6 +840,73 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"竞赛uid",
"竞赛名称",
"竞赛主办方",
"竞赛届数",
"竞赛类型",
"举办状态",
"线上赛开始时间",
"线上赛结束时间",
"线下赛开始时间",
"线下赛结束时间",
"竞赛开始时间",
"竞赛结束时间",
"创建时间"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadContest, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ contestMsg });
watch(searchOptions, (value) => {

View File

@@ -234,6 +234,11 @@
operateLabel="删除答题信息"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出答题数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -243,6 +248,7 @@ import { ElMessage } from "element-plus";
import TabelTools from "../../operate/tabelTools.vue";
import AddNewData from "../../operate/addNewData.vue";
import DownloadData from "../../operate/downloadData.vue";
import TabelSelect from "../../operate/tabelSelect.vue";
import SearchKey from "../../search/searchKey.vue";
import SortSearch from "../../search/sortSearch.vue";
@@ -262,6 +268,7 @@ import $url from "../../../api/url";
import { encrypt } from "../../../utils/aes";
import { judgment } from "../../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../../utils/downloadData.js";
const examinationMsgActive = examinationActiveStore();
@@ -291,6 +298,7 @@ const SortScoreRef = ref(null);
const createdSortDateTimeRef = ref(null);
const updatedSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const downloadDataRef = ref(null);
const editExaminationFormRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
@@ -401,6 +409,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
examinationMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -572,6 +583,67 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"账号uid",
"竞赛uid",
"竞赛类型",
"题目类型",
"得分",
"开始答题时间",
"结束答题时间"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadExamination, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ examinationMsg });
watch(searchOptions, (value) => {

View File

@@ -0,0 +1,451 @@
<template>
<!-- 表格 -->
<el-card>
<div class="flex justify-center flex-wrap">
<TabelTools @showTools="showTools" :dialogObj="snContestMsgActive" />
<AddNewData newDataLabel="添加比赛sn号" @showAddForm="showAddForm" />
<el-table
ref="userTableRef"
:data="tableData"
style="width: 100%"
max-height="32rem"
table-layout="auto"
scrollbar-always-on
>
<el-table-column min-width="100" column-key="sn_number">
<template #header>
<div>
<div>
<el-text class="mx-1"> SN号 </el-text>
<SortSearch
v-if="dialogSortVisible"
ref="SortCardIdRef"
activeText="顺序"
inactiveText="倒序"
@search="snContestMsg"
/>
</div>
</div>
</template>
<template #default="scope">
<div
style="color: rgb(56, 188, 248)"
class="flex justify-start items-center text-base"
>
{{ scope.row.sn_number }}
</div>
</template>
</el-table-column>
<el-table-column min-width="200" width="720" column-key="original_msg">
<template #header>
<SearchKey
v-if="dialogSearchVisible"
ref="SearchOriginalKeyRef"
holderText="输入关键字以搜索相关数据"
@search="snContestMsg"
/>
<div>
<el-text class="mx-1"> 原始数据 </el-text>
</div>
</template>
<template #default="scope">
<div class="flex justify-between items-center text-base">
<el-button
style="font-size: 1rem; font-weight: bold; margin-right: 1rem"
size="small"
type="primary"
plain
disabled
>
{{
scope.row.original_msg.slice(104, scope.row.original_msg.length)
.length / 2
}}个字节
</el-button>
<el-text
truncated
:style="
scope.row.original_msg
? 'color: rgb(56, 188, 248);'
: 'color: rgb(240 70 70);'
"
style="font-size: 1rem"
>
{{
scope.row.original_msg
? scope.row.original_msg.slice(104, scope.row.original_msg.length)
: "解析错误"
}}
</el-text>
<el-button
style="font-size: 1rem; font-weight: bold"
size="small"
type="primary"
plain
@click="
showAll(
scope.row.original_msg.slice(104, scope.row.original_msg.length)
)
"
>
展示全部内容
</el-button>
</div>
</template>
</el-table-column>
<el-table-column min-width="200" width="720" column-key="msg_data">
<template #header>
<SearchKey
v-if="dialogSearchVisible"
ref="SearchDataKeyRef"
holderText="输入关键字以搜索相关数据"
@search="snContestMsg"
/>
<div>
<el-text class="mx-1"> 接收内容 </el-text>
</div>
</template>
<template #default="scope">
<div class="flex justify-between items-center text-base">
<el-text
truncated
:style="
scope.row.msg_data
? 'color: rgb(56, 188, 248);'
: 'color: rgb(240 70 70);'
"
style="font-size: 1rem"
>
{{ scope.row.msg_data ? scope.row.msg_data : "解析错误" }}
</el-text>
<el-button
style="font-size: 1rem; font-weight: bold"
size="small"
type="primary"
plain
@click="showAll(scope.row.msg_data)"
>
展示全部内容
</el-button>
</div>
</template>
</el-table-column>
<el-table-column min-width="170" column-key="created_at">
<template #header>
<div>
<el-text class="mx-1"> 接收时间 </el-text>
<SortSearch
v-if="dialogSortVisible"
ref="SortDateTimeRef"
activeText="顺序"
inactiveText="倒序"
@search="snContestMsg"
/>
</div>
</template>
<template #default="scope">
<div
style="color: rgb(56, 188, 248)"
class="flex justify-start items-center text-base"
>
{{ scope.row.created_at }}
</div>
</template>
</el-table-column>
</el-table>
<!-- 表格 -->
<Pagination
ref="PaginationRef"
:active="snContestMsgActive"
@sizeChangeBack="changePage"
@search="snContestMsg"
/>
</div>
</el-card>
<DataShow ref="DataShowRef" />
<AddSNForm ref="addSNFormRef" title="添加比赛sn号" @reloadData="snContestMsg" />
<DownloadData
ref="downloadDataRef"
operateLabel="导出比赛数据"
@downloadData="executeDownloadData"
/>
</template>
<script setup>
import { ref, reactive, watch, onMounted, onUnmounted, nextTick } from "vue";
import { ElMessage } from "element-plus";
import TabelTools from "../../../operate/tabelTools.vue";
import AddNewData from "../../../operate/addNewData.vue";
import DownloadData from "../../../operate/downloadData.vue";
import AddSNForm from "../../../addNewData/contest/tqxzContest/snForm.vue";
import SearchKey from "../../../search/searchKey.vue";
import SortSearch from "../../../search/sortSearch.vue";
import DateTimePicker from "../../../search/dateTimePicker.vue";
import Pagination from "../../../search/pagination.vue";
import DataShow from "../../../operate/dataShow.vue";
import snContestMsgActiveStore from "../../../../stores/contest/tqxzContest/snContestMsg";
import moment from "moment";
import $http from "../../../../api/index";
import $url from "../../../../api/url";
import { judgment } from "../../../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../../../utils/downloadData.js";
const snContestMsgActive = snContestMsgActiveStore();
const SNArr = ref("");
const time_at = ref("");
const SortCardIdRef = ref(null);
const SortDateTimeRef = ref(null);
const SearchOriginalKeyRef = ref(null);
const SearchDataKeyRef = ref(null);
const PaginationRef = ref(null);
const DataShowRef = ref(null);
const addSNFormRef = ref(null);
const downloadDataRef = ref(null);
const msgInterval = ref(null);
const dialogSearchVisible = ref(false);
const dialogSortVisible = ref(false);
const dialogOperationVisible = ref(false);
const offsetOff = ref(true);
const pageCount = ref(0);
const searchOptions = reactive({
sn_number: "",
original_msg: "",
msg_data: "",
created_at: "",
});
const sortOptions = reactive({
sn_number: false,
created_at: false,
});
const tableData = ref([]);
const showAddForm = () => {
addSNFormRef.value.dialogVisible = true;
};
const showAll = (msg) => {
DataShowRef.value.dialogMsg = msg;
DataShowRef.value.dialogVisible = true;
};
const showTools = (operateType) => {
switch (operateType) {
case "search":
dialogSearchVisible.value = !dialogSearchVisible.value;
snContestMsgActive.dialogSearchVisible = dialogSearchVisible.value;
break;
case "sort":
dialogSortVisible.value = !dialogSortVisible.value;
snContestMsgActive.dialogSortVisible = dialogSortVisible.value;
break;
case "operation":
dialogOperationVisible.value = !dialogOperationVisible.value;
snContestMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
};
const snContestMsg = (fiexdData) => {
if (fiexdData !== undefined) {
const { SNArr, time_at } = fiexdData;
snContestMsgActive.SNArr = SNArr.join(",");
const { contest_start, contest_end } = time_at;
snContestMsgActive.time_at = {
contest_start,
contest_end
};
}
judgment(searchOptions, "original_msg", SearchOriginalKeyRef.value, "searchMsg");
judgment(searchOptions, "msg_data", SearchDataKeyRef.value, "searchMsg");
judgment(sortOptions, "sn_number", SortCardIdRef.value, "searchMsg");
judgment(sortOptions, "created_at", SortDateTimeRef.value, "searchMsg");
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
PaginationRef.value.handleCurrentChange(1);
offsetOff.value = false;
}
} else {
offsetOff.value = true;
}
const data = {
offset: PaginationRef.value.offset,
limit: PaginationRef.value.limit,
searchOptions: searchOptions,
sortOptions: sortOptions,
};
if (snContestMsgActive.SNArr !== "" && snContestMsgActive.time_at !== "") {
data.fiexdData = {
SNArr: snContestMsgActive.SNArr.includes(",") ? SNArr.value = snContestMsgActive.SNArr.split(",") : SNArr.value = [snContestMsgActive.SNArr],
time_at: snContestMsgActive.time_at
}
}
$http.post($url.getSNContestMsg, data).then((res) => {
if (res.data.code === 200) {
tableData.value = res.data.snContestMsg;
tableData.value.forEach((item) => {
item.origin_time = item.created_at;
item.created_at = moment
.utc(item.created_at)
.add(8, "hours")
.format("YYYY-MM-DD-HH:mm:ss");
});
PaginationRef.value.dataCount = res.data.count;
snContestMsgActive.dataCount = PaginationRef.value.dataCount;
pageCount.value = Math.ceil(
PaginationRef.value.dataCount / PaginationRef.value.limit
);
snContestMsgActive.pageCount = pageCount.value;
} else {
tableData.value = [];
// ElMessage.error("未查找到相关数据!");
}
});
};
const changePage = (val) => {
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"SN号",
"原始数据",
"接收内容",
"接收时间"
];
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadSNConest, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ snContestMsg });
watch(searchOptions, (value) => {
snContestMsgActive.searchOptions = value;
});
watch(sortOptions, (value) => {
snContestMsgActive.sortOptions = value;
});
onMounted(() => {
if (snContestMsgActive.SNArr !== "") {
if (snContestMsgActive.SNArr.includes(",")) {
SNArr.value = snContestMsgActive.SNArr.split(",");
} else {
SNArr.value = [snContestMsgActive.SNArr];
}
}
if (snContestMsgActive.time_at !== "") {
time_at.value = snContestMsgActive.time_at;
}
pageCount.value = snContestMsgActive.pageCount;
dialogSearchVisible.value = snContestMsgActive.dialogSearchVisible;
dialogSortVisible.value = snContestMsgActive.dialogSortVisible;
dialogOperationVisible.value = snContestMsgActive.dialogOperationVisible;
if (dialogSearchVisible.value) {
searchOptions.sn_number = snContestMsgActive.searchOptions.sn_number;
searchOptions.original_msg = snContestMsgActive.searchOptions.original_msg;
searchOptions.msg_data = snContestMsgActive.searchOptions.msg_data;
searchOptions.created_at = snContestMsgActive.searchOptions.created_at;
}
if (dialogSortVisible.value) {
sortOptions.sn_number = snContestMsgActive.sortOptions.sn_number;
sortOptions.created_at = snContestMsgActive.sortOptions.created_at;
}
if (dialogOperationVisible.value) {
}
setTimeout(() => {
snContestMsg();
}, 200);
msgInterval.value = setInterval(() => {
if (PaginationRef.value !== null) {
snContestMsg();
}
}, 10000);
setTimeout(() => {
if (dialogSearchVisible.value) {
SearchOriginalKeyRef.value.searchMsg =
snContestMsgActive.searchOptions.original_msg;
SearchDataKeyRef.value.searchMsg = snContestMsgActive.searchOptions.msg_data;
}
if (dialogSortVisible.value) {
SortCardIdRef.value.searchMsg = snContestMsgActive.sortOptions.sn_number;
SortDateTimeRef.value.searchMsg = snContestMsgActive.sortOptions.created_at;
}
if (dialogOperationVisible.value) {
}
}, 0);
});
onUnmounted(() => {
msgInterval.value = null;
});
</script>
<style scoped></style>

View File

@@ -383,6 +383,11 @@
operateLabel="删除C端用户"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出C端用户数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -399,6 +404,7 @@ import DateTimePicker from "../search/dateTimePicker.vue";
import Pagination from "../search/pagination.vue";
import EditCsideForm from "../editData/csideForm.vue";
import PasswordOauth from "../operate/passwordOauth.vue";
import DownloadData from "../operate/downloadData.vue";
import csideActiveStore from "../../stores/cside";
@@ -410,6 +416,7 @@ import $url from "../../api/url";
import { encrypt } from "../../utils/aes";
import { judgment } from "../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../utils/downloadData.js";
const csideMsgActive = csideActiveStore();
@@ -447,6 +454,7 @@ const createdSortDateTimeRef = ref(null);
const updatedSortDateTimeRef = ref(null);
const loginSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const downloadDataRef = ref(null);
const editCsideFormRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
@@ -574,6 +582,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
csideMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -769,6 +780,74 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"账号状态",
"账号角色",
"账号名称",
"用户姓名",
"手机号码",
"性别",
"年龄",
"电子邮箱",
"通信地址",
"邮政编码",
"注册时间",
"账号信息变更时间",
"上次登录时间",
"登录状态"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadCside, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ csideMsg });
watch(searchOptions, (value) => {

View File

@@ -301,6 +301,11 @@
operateLabel="删除公司员工"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出公司员工数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -310,6 +315,7 @@ import { ElMessage } from "element-plus";
import TabelTools from "../operate/tabelTools.vue";
import AddNewData from "../operate/addNewData.vue";
import DownloadData from "../operate/downloadData.vue";
import TabelSelect from "../operate/tabelSelect.vue";
import SearchKey from "../search/searchKey.vue";
import SortSearch from "../search/sortSearch.vue";
@@ -330,6 +336,7 @@ import $url from "../../api/url";
import { encrypt } from "../../utils/aes";
import { judgment } from "../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../utils/downloadData.js";
const insidersMsgActive = insidersActiveStore();
@@ -363,6 +370,7 @@ const updatedSortDateTimeRef = ref(null);
const loginSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const addInsidersFormRef = ref(null);
const downloadDataRef = ref(null);
const editInsidersFormRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
@@ -490,6 +498,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
insidersMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -679,6 +690,70 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"员工uid",
"账号状态",
"账号角色",
"员工姓名",
"所属部门",
"信息变更描述",
"注册时间",
"信息变更时间",
"上次登录时间",
"登录状态"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadInsiders, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ insidersMsg });
watch(searchOptions, (value) => {

View File

@@ -216,6 +216,11 @@
operateLabel="删除系统记录"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出系统记录数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -231,6 +236,7 @@ import SelectSearch from "../search/selectSearch.vue";
import DateTimePicker from "../search/dateTimePicker.vue";
import Pagination from "../search/pagination.vue";
import PasswordOauth from "../operate/passwordOauth.vue";
import DownloadData from "../operate/downloadData.vue";
import monitoringActiveStore from "../../stores/monitoring";
@@ -242,6 +248,7 @@ import $url from "../../api/url";
import { encrypt } from "../../utils/aes";
import { judgment } from "../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../utils/downloadData.js";
const monitoringMsgActive = monitoringActiveStore();
@@ -261,6 +268,7 @@ const SearchNameKeyRef = ref(null);
const createdDateTimePickerRef = ref(null);
const createdSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const downloadDataRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
const dialogSortVisible = ref(false);
@@ -386,6 +394,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
monitoringMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -532,6 +543,68 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"操作名称",
"操作描述",
"危险等级",
"执行状态",
"影响到的数据数目",
"操作者uid",
"操作者姓名",
"行为记录时间"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadMonitoring, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ monitoringMsg });
watch(searchOptions, (value) => {

View File

@@ -282,6 +282,11 @@
operateLabel="删除用户单位"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出用户单位数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
@@ -291,6 +296,7 @@ import { ElMessage } from "element-plus";
import TabelTools from "../operate/tabelTools.vue";
import AddNewData from "../operate/addNewData.vue";
import DownloadData from "../operate/downloadData.vue";
import TabelSelect from "../operate/tabelSelect.vue";
import SearchKey from "../search/searchKey.vue";
import SortSearch from "../search/sortSearch.vue";
@@ -310,6 +316,7 @@ import $url from "../../api/url";
import { encrypt } from "../../utils/aes";
import { judgment } from "../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../utils/downloadData.js";
const organizationMsgActive = organizationActiveStore();
@@ -342,6 +349,7 @@ const createdSortDateTimeRef = ref(null);
const updatedSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const addOrganizationFormRef = ref(null);
const downloadDataRef = ref(null);
const editOrganizationFormRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
@@ -390,6 +398,9 @@ const showTools = (operateType) => {
dialogOperationVisible.value = !dialogOperationVisible.value;
organizationMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
@@ -574,6 +585,70 @@ const requestOperate = () => {
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"单位uid",
"单位名称",
"通信地址",
"联系人姓名",
"联系人电话",
"单位邮箱",
"其他信息",
"邮政编码",
"添加时间",
"上次信息变更时间"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadOrganization, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ organizationMsg });
watch(searchOptions, (value) => {

View File

@@ -0,0 +1,478 @@
<template>
<div>
<!-- 表格 -->
<el-card>
<div class="flex justify-center flex-wrap">
<TabelTools @showTools="showTools" :dialogObj="unknownBDCardRecordMsgActive" />
<el-table
ref="tableRef"
:data="tableData"
style="width: 100%"
max-height="50rem"
table-layout="auto"
scrollbar-always-on
@selection-change="handleSelectionChange"
>
<el-table-column
v-if="dialogOperationVisible"
fixed="left"
type="selection"
width="40"
column-key="selection"
/>
<TabelSelect
v-if="dialogOperationVisible"
ref="DelSelectRef"
:holderText="delSelectHold"
singleColor="danger"
multipleColor="warning"
allColor="danger"
singleSize="small"
multipleSize="small"
allSize="small"
:singlePlain="true"
:multiplePlain="false"
:allPlain="false"
operateType="del"
@showComfirmDialog="showComfirmDialog"
/>
<el-table-column min-width="140" column-key="card_id">
<template #header>
<div>
<SearchKey
v-if="dialogSearchVisible"
ref="SearchCardIDKeyRef"
holderText="输入未知北斗卡卡号以搜索相关数据"
@search="unknownBDCardRecordMsg"
/>
<div>
<el-text class="mx-1"> 未知北斗卡卡号 </el-text>
</div>
</div>
</template>
<template #default="scope">
<div class="flex justify-start items-center text-base">
{{ scope.row.card_id }}
</div>
</template>
</el-table-column>
<el-table-column min-width="140" column-key="original_msg">
<template #header>
<div>
<SearchKey
v-if="dialogSearchVisible"
ref="SearchOriginalMsgKeyRef"
holderText="输入接收数据以搜索相关数据"
@search="unknownBDCardRecordMsg"
/>
<div>
<el-text class="mx-1"> 接收数据 </el-text>
</div>
</div>
</template>
<template #default="scope">
<div class="flex justify-start items-center text-base">
{{ scope.row.original_msg }}
</div>
</template>
</el-table-column>
<el-table-column min-width="140" column-key="msg_data">
<template #header>
<div>
<SearchKey
v-if="dialogSearchVisible"
ref="SearchMsgDataKeyRef"
holderText="输入解析内容以搜索相关数据"
@search="unknownBDCardRecordMsg"
/>
<div>
<el-text class="mx-1"> 解析内容 </el-text>
</div>
</div>
</template>
<template #default="scope">
<div class="flex justify-start items-center text-base">
{{ scope.row.msg_data }}
</div>
</template>
</el-table-column>
<el-table-column min-width="200" column-key="created_at">
<template #header>
<DateTimePicker
v-if="dialogSearchVisible"
ref="createdDateTimePickerRef"
DateTimePicker="createdDateTimePicker"
@search="unknownBDCardRecordMsg"
/>
<div>
<el-text class="mx-1"> 记录时间 </el-text>
<SortSearch
v-if="dialogSortVisible"
ref="createdSortDateTimeRef"
activeText="顺序"
inactiveText="倒序"
@search="unknownBDCardRecordMsg"
/>
</div>
</template>
<template #default="scope">
<div class="flex justify-start items-center text-base">
{{ scope.row.created_at }}
</div>
</template>
</el-table-column>
</el-table>
<!-- 表格 -->
<Pagination
ref="PaginationRef"
:active="unknownBDCardRecordMsgActive"
@sizeChangeBack="changePage"
@search="unknownBDCardRecordMsg"
/>
</div>
</el-card>
<PasswordOauth
ref="delPasswordOauthRef"
operateLabel="删除北斗短报文未知消息记录"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出北斗短报文未知消息记录数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
<script setup>
import { ref, reactive, watch, onMounted, nextTick } from "vue";
import { ElMessage } from "element-plus";
import TabelTools from "../operate/tabelTools.vue";
import TabelSelect from "../operate/tabelSelect.vue";
import SearchKey from "../search/searchKey.vue";
import SortSearch from "../search/sortSearch.vue";
import DateTimePicker from "../search/dateTimePicker.vue";
import Pagination from "../search/pagination.vue";
import PasswordOauth from "../operate/passwordOauth.vue";
import DownloadData from "../operate/downloadData.vue";
import unknownBDCardRecordActiveStore from "../../stores/unknownBDCardRecord.js";
import moment from "moment";
import $http from "../../api/index";
import $url from "../../api/url.js";
import { encrypt } from "../../utils/aes.js";
import { judgment } from "../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../utils/downloadData.js";
const unknownBDCardRecordMsgActive = unknownBDCardRecordActiveStore();
const delSelectHold = {
single: "删除",
multiple: "删除选中",
all: "删除所有",
label: "删除北斗短报文未知消息记录",
};
const DelSelectRef = ref(null);
const SearchCardIDKeyRef = ref(null);
const SearchOriginalMsgKeyRef = ref(null);
const SearchMsgDataKeyRef = ref(null);
const createdDateTimePickerRef = ref(null);
const createdSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const downloadDataRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
const dialogSortVisible = ref(false);
const dialogOperationVisible = ref(false);
const tableRef = ref();
const offsetOff = ref(true);
const pageCount = ref(0);
const operate = ref("del");
const searchOptions = reactive({
card_id: "",
original_msg: "",
msg_data: "",
created_at: "",
});
const sortOptions = reactive({
created_at: false,
});
const tableData = ref([]);
let singleData = reactive({});
let operateData = reactive({});
let operateDataClone = reactive({});
const showTools = (operateType) => {
switch (operateType) {
case "search":
dialogSearchVisible.value = !dialogSearchVisible.value;
unknownBDCardRecordMsgActive.dialogSearchVisible = dialogSearchVisible.value;
break;
case "sort":
dialogSortVisible.value = !dialogSortVisible.value;
unknownBDCardRecordMsgActive.dialogSortVisible = dialogSortVisible.value;
break;
case "operation":
dialogOperationVisible.value = !dialogOperationVisible.value;
unknownBDCardRecordMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
};
const resetOffset = () => {
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
PaginationRef.value.handleCurrentChange(1);
offsetOff.value = false;
}
} else {
offsetOff.value = true;
}
};
const unknownBDCardRecordMsg = () => {
judgment(searchOptions, "card_id", SearchCardIDKeyRef.value, "searchMsg");
judgment(searchOptions, "original_msg", SearchOriginalMsgKeyRef.value, "searchMsg");
judgment(searchOptions, "msg_data", SearchMsgDataKeyRef.value, "searchMsg");
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
resetOffset();
const data = {
uid: localStorage.data,
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
searchOptions: searchOptions,
sortOptions: sortOptions
};
$http.post($url.showUnknownBDCard, data).then((res) => {
if (res.data.code === 200) {
console.log(res.data)
tableData.value = res.data.unknownBDCardRecord;
tableData.value.forEach((item) => {
item.origin_createdAt = item.created_at;
item.created_at = moment
.utc(item.created_at)
.add(0, "hours")
.format("YYYY-MM-DD-HH:mm:ss");
});
PaginationRef.value.dataCount = res.data.count;
unknownBDCardRecordMsgActive.dataCount = PaginationRef.value.dataCount;
pageCount.value = Math.ceil(
PaginationRef.value.dataCount / PaginationRef.value.limit
);
unknownBDCardRecordMsgActive.pageCount = pageCount.value;
if (!operateData[PaginationRef.value.offset]) return;
operateData[PaginationRef.value.offset].forEach((element) => {
tableData.value.forEach((item) => {
if (item.created_at == element.created_at) {
nextTick(() => {
tableRef.value.toggleRowSelection(item, true);
});
}
});
});
} else {
tableData.value = [];
ElMessage.error("未查找到相关数据!");
}
});
};
const changePage = (val) => {
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
operateData = {};
for (let i = 0; i < pageCount.value; i++) {
operateData[i + 1] = [];
for (const key in operateDataClone) {
operateDataClone[key].forEach((element) => {
// 判断数据在第几页
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
operateData[i + 1].push(element);
}
});
}
}
};
const handleSelectionChange = (val) => {
operateData[PaginationRef.value.offset] = val;
tableData.value.forEach((item, index) => {
operateData[PaginationRef.value.offset].forEach((element) => {
if (item.created_at == element.created_at) {
// 数据在表格中的位置
element.location = (PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
}
});
});
operateDataClone = JSON.parse(JSON.stringify(operateData));
for (const key in operateDataClone) {
operateDataClone[key].forEach((item) => {
if (item.origin_createdAt) {
item.created_at = item.origin_createdAt;
}
delete item.origin_createdAt;
delete item.location;
});
}
};
const showComfirmDialog = (singleMsg) => {
singleData = { ...singleMsg.data };
singleData.created_at = singleData.origin_createdAt;
delete singleData.origin_createdAt;
operate.value = singleMsg.operateType;
if (singleMsg.operateType == "del") {
delPasswordOauthRef.value.operateDialogVisible = true;
}
};
const requestOperate = () => {
let operateType, url, model, password;
if (operate.value == "del") {
operateType = "删除";
url = $url.deleteUnknownBDCard;
model = DelSelectRef.value.model;
password = delPasswordOauthRef.value.ruleForm.password;
}
const data = {
uid: localStorage.data,
model: encrypt(model),
password: encrypt(password),
requestMsg: model == "single" ? singleData : model == "multiple" ? operateDataClone : ""
};
$http.post(url, data).then((res) => {
if (res.data.code === 200) {
tableRef.value.clearSelection();
operateData = {};
operateDataClone = {};
ElMessage({
message: `${operateType}成功!`,
type: "success",
});
unknownBDCardRecordMsg();
} else {
ElMessage.error(`${operateType}失败!`);
}
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"接收数据",
"解析内容",
"记录时间"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadUnknownBDCard, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ unknownBDCardRecordMsg });
watch(searchOptions, (value) => {
unknownBDCardRecordMsgActive.searchOptions = value;
});
watch(sortOptions, (value) => {
unknownBDCardRecordMsgActive.sortOptions = value;
});
onMounted(() => {
pageCount.value = unknownBDCardRecordMsgActive.pageCount;
dialogSearchVisible.value = unknownBDCardRecordMsgActive.dialogSearchVisible;
dialogSortVisible.value = unknownBDCardRecordMsgActive.dialogSortVisible;
dialogOperationVisible.value = unknownBDCardRecordMsgActive.dialogOperationVisible;
if (dialogSearchVisible.value) {
searchOptions.card_id = unknownBDCardRecordMsgActive.searchOptions.card_id;
searchOptions.original_msg = unknownBDCardRecordMsgActive.searchOptions.original_msg;
searchOptions.msg_data = unknownBDCardRecordMsgActive.searchOptions.msg_data;
searchOptions.created_at = unknownBDCardRecordMsgActive.searchOptions.created_at;
}
if (dialogSortVisible.value) {
sortOptions.created_at = unknownBDCardRecordMsgActive.sortOptions.created_at;
}
if (dialogOperationVisible.value) {
}
setTimeout(() => {
unknownBDCardRecordMsg();
}, 200);
setTimeout(() => {
if (dialogSearchVisible.value) {
SearchCardIDKeyRef.value.searchMsg = unknownBDCardRecordMsgActive.searchOptions.card_id;
SearchOriginalMsgKeyRef.value.searchMsg = unknownBDCardRecordMsgActive.searchOptions.original_msg;
SearchMsgDataKeyRef.value.searchMsg = unknownBDCardRecordMsgActive.searchOptions.msg_data;
createdDateTimePickerRef.value.created_at = unknownBDCardRecordMsgActive.searchOptions.created_at;
}
if (dialogSortVisible.value) {
createdSortDateTimeRef.value.searchMsg = unknownBDCardRecordMsgActive.sortOptions.created_at;
}
if (dialogOperationVisible.value) {
}
}, 0);
});
</script>
<style scoped></style>

View File

@@ -0,0 +1,503 @@
<template>
<div>
<!-- 表格 -->
<el-card>
<div class="flex justify-center flex-wrap">
<TabelTools @showTools="showTools" :dialogObj="unknownSNRecordMsgActive" />
<el-table
ref="tableRef"
:data="tableData"
style="width: 100%"
max-height="50rem"
table-layout="auto"
scrollbar-always-on
@selection-change="handleSelectionChange"
>
<el-table-column
v-if="dialogOperationVisible"
fixed="left"
type="selection"
width="40"
column-key="selection"
/>
<TabelSelect
v-if="dialogOperationVisible"
ref="DelSelectRef"
:holderText="delSelectHold"
singleColor="danger"
multipleColor="warning"
allColor="danger"
singleSize="small"
multipleSize="small"
allSize="small"
:singlePlain="true"
:multiplePlain="false"
:allPlain="false"
operateType="del"
@showComfirmDialog="showComfirmDialog"
/>
<el-table-column min-width="140" column-key="msg_id">
<template #header>
<div>
<SearchKey
v-if="dialogSearchVisible"
ref="SearchMsgIDKeyRef"
holderText="输入消息id以搜索相关数据"
@search="unknownSNRecordMsg"
/>
<div>
<el-text class="mx-1"> 消息id </el-text>
</div>
</div>
</template>
<template #default="scope">
<div class="flex justify-start items-center text-base">
{{ scope.row.msg_id }}
</div>
</template>
</el-table-column>
<el-table-column min-width="140" column-key="sn_number">
<template #header>
<div>
<SearchKey
v-if="dialogSearchVisible"
ref="SearchSNNumberKeyRef"
holderText="输入未知天启星座机器SN号以搜索相关数据"
@search="unknownSNRecordMsg"
/>
<div>
<el-text class="mx-1"> 未知天启星座机器SN号 </el-text>
</div>
</div>
</template>
<template #default="scope">
<div class="flex justify-start items-center text-base">
{{ scope.row.sn_number }}
</div>
</template>
</el-table-column>
<el-table-column min-width="140" column-key="original_msg">
<template #header>
<div>
<SearchKey
v-if="dialogSearchVisible"
ref="SearchOriginalMsgKeyRef"
holderText="输入接收数据以搜索相关数据"
@search="unknownSNRecordMsg"
/>
<div>
<el-text class="mx-1"> 接收数据 </el-text>
</div>
</div>
</template>
<template #default="scope">
<div class="flex justify-start items-center text-base">
{{ scope.row.original_msg }}
</div>
</template>
</el-table-column>
<el-table-column min-width="140" column-key="msg_data">
<template #header>
<div>
<SearchKey
v-if="dialogSearchVisible"
ref="SearchMsgDataKeyRef"
holderText="输入解析内容以搜索相关数据"
@search="unknownSNRecordMsg"
/>
<div>
<el-text class="mx-1"> 解析内容 </el-text>
</div>
</div>
</template>
<template #default="scope">
<div class="flex justify-start items-center text-base">
{{ scope.row.msg_data }}
</div>
</template>
</el-table-column>
<el-table-column min-width="200" column-key="created_at">
<template #header>
<DateTimePicker
v-if="dialogSearchVisible"
ref="createdDateTimePickerRef"
DateTimePicker="createdDateTimePicker"
@search="unknownSNRecordMsg"
/>
<div>
<el-text class="mx-1"> 记录时间 </el-text>
<SortSearch
v-if="dialogSortVisible"
ref="createdSortDateTimeRef"
activeText="顺序"
inactiveText="倒序"
@search="unknownSNRecordMsg"
/>
</div>
</template>
<template #default="scope">
<div class="flex justify-start items-center text-base">
{{ scope.row.created_at }}
</div>
</template>
</el-table-column>
</el-table>
<!-- 表格 -->
<Pagination
ref="PaginationRef"
:active="unknownSNRecordMsgActive"
@sizeChangeBack="changePage"
@search="unknownSNRecordMsg"
/>
</div>
</el-card>
<PasswordOauth
ref="delPasswordOauthRef"
operateLabel="删除天启SN号未知消息记录"
@requestOperate="requestOperate"
/>
<DownloadData
ref="downloadDataRef"
operateLabel="导出天启SN号未知消息记录数据"
@downloadData="executeDownloadData"
/>
</div>
</template>
<script setup>
import { ref, reactive, watch, onMounted, nextTick } from "vue";
import { ElMessage } from "element-plus";
import TabelTools from "../operate/tabelTools.vue";
import TabelSelect from "../operate/tabelSelect.vue";
import SearchKey from "../search/searchKey.vue";
import SortSearch from "../search/sortSearch.vue";
import DateTimePicker from "../search/dateTimePicker.vue";
import Pagination from "../search/pagination.vue";
import PasswordOauth from "../operate/passwordOauth.vue";
import DownloadData from "../operate/downloadData.vue";
import unknownSNRecordActiveStore from "../../stores/unknownSNRecord.js";
import moment from "moment";
import $http from "../../api/index";
import $url from "../../api/url.js";
import { encrypt } from "../../utils/aes.js";
import { judgment } from "../../utils/judgment.js";
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
import { downloadData } from "../../utils/downloadData.js";
const unknownSNRecordMsgActive = unknownSNRecordActiveStore();
const delSelectHold = {
single: "删除",
multiple: "删除选中",
all: "删除所有",
label: "删除天启SN号未知消息记录",
};
const DelSelectRef = ref(null);
const SearchMsgIDKeyRef = ref(null);
const SearchSNNumberKeyRef = ref(null);
const SearchOriginalMsgKeyRef = ref(null);
const SearchMsgDataKeyRef = ref(null);
const createdDateTimePickerRef = ref(null);
const createdSortDateTimeRef = ref(null);
const PaginationRef = ref(null);
const downloadDataRef = ref(null);
const delPasswordOauthRef = ref(null);
const dialogSearchVisible = ref(false);
const dialogSortVisible = ref(false);
const dialogOperationVisible = ref(false);
const tableRef = ref();
const offsetOff = ref(true);
const pageCount = ref(0);
const operate = ref("del");
const searchOptions = reactive({
msg_id: "",
sn_number: "",
original_msg: "",
msg_data: "",
created_at: "",
});
const sortOptions = reactive({
created_at: false,
});
const tableData = ref([]);
let singleData = reactive({});
let operateData = reactive({});
let operateDataClone = reactive({});
const showTools = (operateType) => {
switch (operateType) {
case "search":
dialogSearchVisible.value = !dialogSearchVisible.value;
unknownSNRecordMsgActive.dialogSearchVisible = dialogSearchVisible.value;
break;
case "sort":
dialogSortVisible.value = !dialogSortVisible.value;
unknownSNRecordMsgActive.dialogSortVisible = dialogSortVisible.value;
break;
case "operation":
dialogOperationVisible.value = !dialogOperationVisible.value;
unknownSNRecordMsgActive.dialogOperationVisible = dialogOperationVisible.value;
break;
case "downloadData":
downloadDataRef.value.downloadDataDialogVisible = true;
break;
default:
break;
}
};
const resetOffset = () => {
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
PaginationRef.value.handleCurrentChange(1);
offsetOff.value = false;
}
} else {
offsetOff.value = true;
}
};
const unknownSNRecordMsg = () => {
judgment(searchOptions, "msg_id", SearchMsgIDKeyRef.value, "searchMsg");
judgment(searchOptions, "sn_number", SearchSNNumberKeyRef.value, "searchMsg");
judgment(searchOptions, "original_msg", SearchOriginalMsgKeyRef.value, "searchMsg");
judgment(searchOptions, "msg_data", SearchMsgDataKeyRef.value, "searchMsg");
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
resetOffset();
const data = {
uid: localStorage.data,
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
searchOptions: searchOptions,
sortOptions: sortOptions
};
$http.post($url.showUnknownSN, data).then((res) => {
if (res.data.code === 200) {
console.log(res.data)
tableData.value = res.data.unknownSNRecord;
tableData.value.forEach((item) => {
item.origin_createdAt = item.created_at;
item.created_at = moment
.utc(item.created_at)
.add(0, "hours")
.format("YYYY-MM-DD-HH:mm:ss");
});
PaginationRef.value.dataCount = res.data.count;
unknownSNRecordMsgActive.dataCount = PaginationRef.value.dataCount;
pageCount.value = Math.ceil(
PaginationRef.value.dataCount / PaginationRef.value.limit
);
unknownSNRecordMsgActive.pageCount = pageCount.value;
if (!operateData[PaginationRef.value.offset]) return;
operateData[PaginationRef.value.offset].forEach((element) => {
tableData.value.forEach((item) => {
if (item.created_at == element.created_at) {
nextTick(() => {
tableRef.value.toggleRowSelection(item, true);
});
}
});
});
} else {
tableData.value = [];
ElMessage.error("未查找到相关数据!");
}
});
};
const changePage = (val) => {
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
operateData = {};
for (let i = 0; i < pageCount.value; i++) {
operateData[i + 1] = [];
for (const key in operateDataClone) {
operateDataClone[key].forEach((element) => {
// 判断数据在第几页
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
operateData[i + 1].push(element);
}
});
}
}
};
const handleSelectionChange = (val) => {
operateData[PaginationRef.value.offset] = val;
tableData.value.forEach((item, index) => {
operateData[PaginationRef.value.offset].forEach((element) => {
if (item.created_at == element.created_at) {
// 数据在表格中的位置
element.location = (PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
}
});
});
operateDataClone = JSON.parse(JSON.stringify(operateData));
for (const key in operateDataClone) {
operateDataClone[key].forEach((item) => {
if (item.origin_createdAt) {
item.created_at = item.origin_createdAt;
}
delete item.origin_createdAt;
delete item.location;
});
}
};
const showComfirmDialog = (singleMsg) => {
singleData = { ...singleMsg.data };
singleData.created_at = singleData.origin_createdAt;
delete singleData.origin_createdAt;
operate.value = singleMsg.operateType;
if (singleMsg.operateType == "del") {
delPasswordOauthRef.value.operateDialogVisible = true;
}
};
const requestOperate = () => {
let operateType, url, model, password;
if (operate.value == "del") {
operateType = "删除";
url = $url.deleteUnknownSN;
model = DelSelectRef.value.model;
password = delPasswordOauthRef.value.ruleForm.password;
}
const data = {
uid: localStorage.data,
model: encrypt(model),
password: encrypt(password),
requestMsg: model == "single" ? singleData : model == "multiple" ? operateDataClone : ""
};
$http.post(url, data).then((res) => {
if (res.data.code === 200) {
tableRef.value.clearSelection();
operateData = {};
operateDataClone = {};
ElMessage({
message: `${operateType}成功!`,
type: "success",
});
unknownSNRecordMsg();
} else {
ElMessage.error(`${operateType}失败!`);
}
});
};
const executeDownloadData = (form) => {
// 根据数据量大小来决定在前端还是后端导出数据
if (
tableData.value == [] ||
tableData.value == undefined ||
PaginationRef.value.dataCount == 0 ||
PaginationRef.value.dataCount == null
) {
ElMessage.error("暂无数据!");
return;
}
let dataClone = JSON.parse(JSON.stringify(tableData.value));
dataClone.forEach((item) => {
delete item.origin_time;
});
const dataHeaders = [
"接收数据",
"解析内容",
"记录时间"
];
downloadData(form, dataClone, dataHeaders);
if (PaginationRef.value.dataCount <= PaginationRef.value.limit) {
downloadData(form, dataClone, dataHeaders);
} else {
const data = {
form,
searchMsg: {
searchOptions: searchOptions,
sortOptions: sortOptions,
},
dataHeaders,
};
$http.post($url.downloadUnknownSN, data).then((res) => {
if (res.data.code === 200) {
ElMessage({
message: "数据导出成功!",
type: "success",
});
// 创建一个隐藏的<a>标签
const link = document.createElement("a");
link.style.display = "none";
link.href = res.data.fileUrl;
// 设置下载的文件名
link.download = res.data.fileName;
// 触发点击事件来下载文件
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
} else {
ElMessage.error("数据导出失败!");
}
});
}
};
defineExpose({ unknownSNRecordMsg });
watch(searchOptions, (value) => {
unknownSNRecordMsgActive.searchOptions = value;
});
watch(sortOptions, (value) => {
unknownSNRecordMsgActive.sortOptions = value;
});
onMounted(() => {
pageCount.value = unknownSNRecordMsgActive.pageCount;
dialogSearchVisible.value = unknownSNRecordMsgActive.dialogSearchVisible;
dialogSortVisible.value = unknownSNRecordMsgActive.dialogSortVisible;
dialogOperationVisible.value = unknownSNRecordMsgActive.dialogOperationVisible;
if (dialogSearchVisible.value) {
searchOptions.msg_id = unknownSNRecordMsgActive.searchOptions.msg_id;
searchOptions.sn_number = unknownSNRecordMsgActive.searchOptions.sn_number;
searchOptions.original_msg = unknownSNRecordMsgActive.searchOptions.original_msg;
searchOptions.msg_data = unknownSNRecordMsgActive.searchOptions.msg_data;
searchOptions.created_at = unknownSNRecordMsgActive.searchOptions.created_at;
}
if (dialogSortVisible.value) {
sortOptions.created_at = unknownSNRecordMsgActive.sortOptions.created_at;
}
if (dialogOperationVisible.value) {
}
setTimeout(() => {
unknownSNRecordMsg();
}, 200);
setTimeout(() => {
if (dialogSearchVisible.value) {
SearchMsgIDKeyRef.value.searchMsg = unknownSNRecordMsgActive.searchOptions.msg_id;
SearchSNNumberKeyRef.value.searchMsg = unknownSNRecordMsgActive.searchOptions.sn_number;
SearchOriginalMsgKeyRef.value.searchMsg = unknownSNRecordMsgActive.searchOptions.original_msg;
SearchMsgDataKeyRef.value.searchMsg = unknownSNRecordMsgActive.searchOptions.msg_data;
createdDateTimePickerRef.value.created_at = unknownSNRecordMsgActive.searchOptions.created_at;
}
if (dialogSortVisible.value) {
createdSortDateTimeRef.value.searchMsg = unknownSNRecordMsgActive.sortOptions.created_at;
}
if (dialogOperationVisible.value) {
}
}, 0);
});
</script>
<style scoped></style>

View File

@@ -0,0 +1,167 @@
<template>
<el-dialog
v-model="downloadDataDialogVisible"
:show-close="false"
style="width: 80%"
center
align-center
>
<template #header="{ titleId, titleClass }">
<div
style="font-size: 2rem"
class="w-full font-bold"
:id="titleId"
:class="titleClass"
>
{{ operateLabel }}
</div>
<div
@click="resetCheckForm(ruleFormRef)"
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
>
<el-icon>
<CloseBold />
</el-icon>
</div>
</template>
<el-form
ref="ruleFormRef"
style="max-width: 600px"
:model="ruleForm"
:rules="rules"
label-width="auto"
size="default"
status-icon
class="mx-auto text-center"
>
<el-text class="mx-1" size="small" type="danger">
如果需要导出符合一定条件的数据,请先使用表格工具来对表格进行操作,然后再进行数据导出。
</el-text>
<el-form-item class="mx-1 font-bold" label="工作表名称" prop="sheetName">
<el-input
clearable
placeholder="请输入工作表名称"
autocomplete="off"
v-model="ruleForm.sheetName"
@input="filter(ruleForm.sheetName, 'sheetName')"
/>
</el-form-item>
<el-form-item class="mx-1 font-bold" label="文件名称" prop="fileName">
<el-input
clearable
placeholder="请输入文件名称"
autocomplete="off"
v-model="ruleForm.fileName"
@input="filter(ruleForm.fileName, 'fileName')"
/>
</el-form-item>
<el-form-item class="mx-1 font-bold" label="文件类型" prop="extensionType">
<el-select
clearable
size="small"
placeholder="请选择文件类型"
autocomplete="off"
v-model="ruleForm.extensionType"
style="width: 100%; font-size: 1rem"
>
<el-option
v-for="item in extensionTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
class="text-center"
:style="item.style"
/>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button style="font-weight: bold" @click="resetCheckForm(ruleFormRef)">
取消
</el-button>
<el-button style="font-weight: bold" type="primary" @click="confirm(ruleFormRef)">
确定
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, reactive } from "vue";
import { CloseBold } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
const downloadDataDialogVisible = ref(false);
const ruleFormRef = ref(null);
const formElClone = ref(null);
const ruleForm = reactive({
sheetName: "",
fileName: "",
extensionType: "",
});
const extensionTypeOptions = [
{
value: "0",
label: "xlsx文件(推荐)",
style: "color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);",
},
{
value: "1",
label: "xls文件",
style: "color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);",
},
{
value: "2",
label: "csv文件(数据库导入专用)",
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);",
},
];
const rules = reactive({
sheetName: [{ required: true, message: "请输入工作表名称", trigger: "blur" }],
fileName: [{ required: true, message: "请输入文件名称", trigger: "blur" }],
extensionType: [{ required: true, message: "请选择文件类型", trigger: "blur" }],
});
const props = defineProps({
operateLabel: String,
});
const emit = defineEmits(["downloadData"]);
const filter = (value, label) => {
if (/[=\s"'+-]/.test(value)) {
if (ruleForm[label]) {
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
}
}
};
const resetCheckForm = (formEl) => {
downloadDataDialogVisible.value = false;
if (!formEl) return;
formEl.resetFields();
};
const confirm = async (formEl) => {
if (!formEl) return;
await formEl.validate((valid) => {
if (valid) {
formElClone.value = JSON.parse(JSON.stringify(ruleForm));
emit("downloadData", formElClone.value);
downloadDataDialogVisible.value = false;
formEl.resetFields();
} else {
ElMessage.error("提交失败!");
}
});
};
defineExpose({ downloadDataDialogVisible });
</script>
<style scoped></style>

View File

@@ -36,6 +36,18 @@
</el-icon>
</el-link>
</el-dropdown-item>
<el-dropdown-item
style="background-color: rgba(255, 200, 0, 0.1)"
@click="showTools('downloadData')"
>
<el-link
style="font-weight: bold; color: rgba(255, 200, 0)"
:underline="false"
type="success"
>
导出数据
</el-link>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
@@ -74,6 +86,9 @@ const showTools = (operateType) => {
emit("showTools", "operation");
showOperation.value = !showOperation.value;
break;
case "downloadData":
emit("showTools", "downloadData");
break;
default:
break;
}

View File

@@ -62,6 +62,12 @@ const router = createRouter({
meta: { label: "北斗卡绑定记录" },
component: () => import('../components/mainPage/bindRecord.vue')
},
{
path: "unknownBDCard",
name: "unknownBDCard",
meta: { label: "未知北斗短报文记录" },
component: () => import('../components/mainPage/unknownBDCard.vue')
},
{
path: "SNData",
name: "SNData",
@@ -80,6 +86,12 @@ const router = createRouter({
meta: { label: "SN号绑定记录" },
component: () => import('../components/mainPage/bindSNRecord.vue')
},
{
path: "unknownSN",
name: "unknownSN",
meta: { label: "未知天启消息记录" },
component: () => import('../components/mainPage/unknownSN.vue')
},
]
},
{
@@ -178,6 +190,12 @@ const router = createRouter({
name: "contestGrades",
meta: { label: "竞赛成绩管理" },
component: () => import('../components/mainPage/contest/examination.vue')
},
{
path: "snContestMsg",
name: "snContestMsg",
meta: { label: "SN号竞赛消息" },
component: () => import('../components/mainPage/contest/tqxzContest/snContestMsg.vue')
}
]
},

View File

@@ -0,0 +1,45 @@
import { defineStore } from 'pinia';
import { parse, stringify } from 'zipson';
const snContestMsgActiveStore = defineStore('snContestMsg', {
state: () => ({
// 持久化数据
activeIndex: "1",
subActiveIndex: "1",
SNArr: "",
time_at: "",
offset: 1,
limit: 10,
dataCount: 0,
pageCount: 0,
searchOptions: {
sn_number: "",
original_msg: "",
msg_data: "",
created_at: "",
},
sortOptions: {
sn_number: false,
created_at: false,
},
dialogSearchVisible: false,
dialogSortVisible: false,
dialogOperationVisible: false
}),
persist: {
enabled: true, // Store 中数据持久化生效
strategies: [
{
key: 'snContestMsgActive', // 存储的 key
storage: localStorage, // 存储位置
paths: ["activeIndex", "subActiveIndex", "SNArr", "time_at", "offset", "limit", "dataCount", "pageCount", "searchOptions", "sortOptions", "dialogSearchVisible", "dialogSortVisible", "dialogOperationVisible"], // 需要持久化的字段
serializer: {
deserialize: parse,
serialize: stringify,
},
}
]
},
});
export default snContestMsgActiveStore;

View File

@@ -0,0 +1,43 @@
import { defineStore } from 'pinia';
import { parse, stringify } from 'zipson';
const unknownBDCardRecordActiveStore = defineStore('unknownBDCardRecord', {
state: () => ({
// 持久化数据
activeIndex: "1",
offset: 1,
limit: 10,
dataCount: 0,
pageCount: 0,
searchOptions: {
original_msg: "",
msg_data: "",
created_at: "",
},
sortOptions: {
created_at: false,
},
dialogSearchVisible: false,
dialogSortVisible: false,
dialogOperationVisible: false,
dialogSingleVisible: true,
dialogMultipleVisible: false,
dialogExcleVisible: false,
}),
persist: {
enabled: true, // Store 中数据持久化生效
strategies: [
{
key: 'unknownBDCardRecordActiveStore', // 存储的 key
storage: localStorage, // 存储位置
paths: ["activeIndex", "offset", "limit", "dataCount", "pageCount", "searchOptions", "sortOptions", "dialogSearchVisible", "dialogSortVisible", "dialogOperationVisible"], // 需要持久化的字段
serializer: {
deserialize: parse,
serialize: stringify,
},
}
]
},
});
export default unknownBDCardRecordActiveStore;

View File

@@ -0,0 +1,43 @@
import { defineStore } from 'pinia';
import { parse, stringify } from 'zipson';
const unknownSNRecordActiveStore = defineStore('unknownSNRecord', {
state: () => ({
// 持久化数据
activeIndex: "1",
offset: 1,
limit: 10,
dataCount: 0,
pageCount: 0,
searchOptions: {
original_msg: "",
msg_data: "",
created_at: "",
},
sortOptions: {
created_at: false,
},
dialogSearchVisible: false,
dialogSortVisible: false,
dialogOperationVisible: false,
dialogSingleVisible: true,
dialogMultipleVisible: false,
dialogExcleVisible: false,
}),
persist: {
enabled: true, // Store 中数据持久化生效
strategies: [
{
key: 'unknownSNRecordActiveStore', // 存储的 key
storage: localStorage, // 存储位置
paths: ["activeIndex", "offset", "limit", "dataCount", "pageCount", "searchOptions", "sortOptions", "dialogSearchVisible", "dialogSortVisible", "dialogOperationVisible"], // 需要持久化的字段
serializer: {
deserialize: parse,
serialize: stringify,
},
}
]
},
});
export default unknownSNRecordActiveStore;

21
src/utils/downloadData.js Normal file
View File

@@ -0,0 +1,21 @@
import * as XLSX from 'xlsx';
export const downloadData = (form, data, dataHeaders) => {
const { sheetName, fileName, extensionType } = form;
let extensionName = ['.xlsx', '.xls', '.csv'];
// 将数据转换为工作表
const ws = XLSX.utils.json_to_sheet(data);
// 动态设置表头
dataHeaders.forEach((header, index) => {
const cellRef = XLSX.utils.encode_cell({ r: 0, c: index }); // 生成单元格引用,如A1, B1等
ws[cellRef] = { v: header, t: "s" }; // 设置单元格的值和类型
});
// 创建一个新的工作簿并添加工作表
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, sheetName);
// 生成 Excel 文件并下载
XLSX.writeFile(wb, fileName + extensionName[extensionType]); // 这里可以自定义文件名和扩展名};
}

View File

@@ -25,6 +25,7 @@ const menu = [
{ label: "竞赛信息管理", path: "contestMsg", id: 2 },
{ label: "竞赛账号管理", path: "contestAccount", id: 3 },
{ label: "竞赛成绩管理", path: "contestGrades", id: 4 },
{ label: "SN号竞赛消息", path: "snContestMsg", id: 5 },
];
onMounted(() => {

View File

@@ -23,9 +23,11 @@ const menu = [
{ label: "北斗卡数据统计", path: "bdCardData", id: 0 },
{ label: "北斗卡管理", path: "bdCard", id: 1 },
{ label: "北斗卡绑定记录", path: "bindRecord", id: 2 },
{ label: "SN号数据统计", path: "SNData", id: 3 },
{ label: "SN号管理", path: "SN", id: 4 },
{ label: "SN号绑定记录", path: "bindSNRecord", id: 5 },
{ label: "未知北斗短报文消息记录", path: "unknownBDCard", id: 3 },
{ label: "SN号数据统计", path: "SNData", id: 4 },
{ label: "SN号管理", path: "SN", id: 5 },
{ label: "SN号绑定记录", path: "bindSNRecord", id: 6 },
{ label: "未知天启消息记录", path: "unknownSN", id: 7 },
];
onMounted(() => {