北斗导航定位通信综合实践赛服务系统
This commit is contained in:
186
src/components/manager/bind.vue
Normal file
186
src/components/manager/bind.vue
Normal file
@@ -0,0 +1,186 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ close, titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
绑定
|
||||
</div>
|
||||
<div
|
||||
@click="close"
|
||||
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"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="卡号" prop="card_id">
|
||||
<el-input
|
||||
minlength="8"
|
||||
maxlength="8"
|
||||
clearable
|
||||
placeholder="请输入卡号"
|
||||
v-model="ruleForm.card_id"
|
||||
@input="filter(ruleForm.card_id, 'card_id')"
|
||||
@blur="serviceCheck(ruleForm.card_id)"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="IMSI 号" prop="card_imsi">
|
||||
<el-input
|
||||
minlength="18"
|
||||
maxlength="18"
|
||||
clearable
|
||||
placeholder="请输入 IMSI 号"
|
||||
v-model="ruleForm.card_imsi"
|
||||
@input="filter(ruleForm.card_imsi, 'card_imsi')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="bind(ruleFormRef)">
|
||||
绑定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const ruleFormRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
card_id: "",
|
||||
card_imsi: "",
|
||||
});
|
||||
|
||||
const rules = reactive({
|
||||
card_id: [
|
||||
{ required: true, message: "请输入卡号", trigger: "blur" },
|
||||
{ min: 8, max: 8, message: "输入长度应当为 8 位", trigger: "change" },
|
||||
],
|
||||
card_imsi: [
|
||||
{ required: true, message: "请输入 IMSI 号", trigger: "blur" },
|
||||
{ min: 18, max: 18, message: "输入长度应当为 18 位", trigger: "change" },
|
||||
],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["bindCard", "connect"]);
|
||||
|
||||
const props = defineProps({
|
||||
card_id: String,
|
||||
});
|
||||
|
||||
const filter = (value, label) => {
|
||||
let filterValue = value.replace(/\D/g, "");
|
||||
if (label == "card_id") {
|
||||
ruleForm.card_id = filterValue;
|
||||
} else if (label == "card_imsi") {
|
||||
ruleForm.card_imsi = filterValue;
|
||||
}
|
||||
};
|
||||
|
||||
const serviceCheck = (card_id) => {
|
||||
if (card_id !== "" && card_id !== undefined) {
|
||||
const data = {
|
||||
card_id,
|
||||
};
|
||||
$http.post($url.checkBind, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
ElMessage({
|
||||
message: "可绑定!",
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("此卡号已被绑定!");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const resetForm = (formEl) => {
|
||||
dialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
|
||||
const bind = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
dialogVisible.value = false;
|
||||
const data = {
|
||||
card_id: ruleForm.card_id,
|
||||
card_imsi: ruleForm.card_imsi,
|
||||
};
|
||||
$http.post($url.bindCard, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
ElMessage({
|
||||
message: "绑定成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("bindCard", ruleForm.card_id);
|
||||
ruleForm.card_id = "";
|
||||
ruleForm.card_imsi = "";
|
||||
emit("connect");
|
||||
window.location.reload();
|
||||
} else {
|
||||
ElMessage.error("绑定失败!");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
|
||||
watch(dialogVisible, (value) => {
|
||||
if (!value) {
|
||||
resetForm(ruleFormRef.value);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
173
src/components/manager/changePassword.vue
Normal file
173
src/components/manager/changePassword.vue
Normal file
@@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" title="密码管理" width="600" center align-center>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
>
|
||||
<el-form-item label="原密码" prop="oldPassword">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入原密码"
|
||||
type="password"
|
||||
show-password
|
||||
maxlength="16"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.oldPassword"
|
||||
@input="filter(ruleForm.oldPassword, 'oldPassword')"
|
||||
oncut="return false"
|
||||
onpaste="return false"
|
||||
oncopy="return false"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword">
|
||||
<el-text class="mx-1" size="small" type="info">
|
||||
密码必须包含数字、大小写字母以及特殊字符(!@#$%^&*),且长度在8-16位之间
|
||||
</el-text>
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入新密码"
|
||||
type="password"
|
||||
show-password
|
||||
maxlength="16"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.newPassword"
|
||||
@input="filter(ruleForm.newPassword, 'newPassword')"
|
||||
oncut="return false"
|
||||
onpaste="return false"
|
||||
oncopy="return false"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认新密码" prop="checkPass">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请再次输入新密码"
|
||||
type="checkPass"
|
||||
show-password
|
||||
maxlength="16"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.checkPass"
|
||||
@input="filter(ruleForm.checkPass, 'checkPass')"
|
||||
oncut="return false"
|
||||
onpaste="return false"
|
||||
oncopy="return false"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="resetForm(ruleFormRef)">取消</el-button>
|
||||
<el-button type="primary" @click="changePassword(ruleFormRef)">
|
||||
提交修改
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import { encrypt } from "../../utils/aes";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
|
||||
const ruleFormRef = ref();
|
||||
const ruleForm = reactive({
|
||||
oldPassword: "",
|
||||
newPassword: "",
|
||||
checkPass: "",
|
||||
});
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const passwordRegex = /^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]).{8,16}$/;
|
||||
|
||||
const validatePass = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入密码"));
|
||||
} else if (!passwordRegex.test(value)) {
|
||||
callback(
|
||||
new Error(
|
||||
"密码必须包含数字、大小写字母以及特殊字符(!@#$%^&*),且长度在8-16位之间"
|
||||
)
|
||||
);
|
||||
} else {
|
||||
if (ruleForm.checkPass !== "") {
|
||||
if (!ruleFormRef.value) return;
|
||||
ruleFormRef.value.validateField("checkPass");
|
||||
}
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const validateCheck = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请再次输入密码"));
|
||||
} else if (value !== ruleForm.newPassword) {
|
||||
callback(new Error("两次输入的密码不一致"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const rules = reactive({
|
||||
oldPassword: [{ required: true, message: "请输入原密码", trigger: "blur" }],
|
||||
newPassword: [{ required: true, validator: validatePass, trigger: "blur" }],
|
||||
checkPass: [{ required: true, validator: validateCheck, trigger: "blur" }],
|
||||
});
|
||||
|
||||
const resetForm = (formEl) => {
|
||||
dialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
|
||||
const changePassword = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
dialogVisible.value = false;
|
||||
let encryptForm = {
|
||||
oldPassword: encrypt(ruleForm.oldPassword),
|
||||
newPassword: encrypt(ruleForm.newPassword),
|
||||
};
|
||||
formEl.resetFields();
|
||||
const data = {
|
||||
passwordForm: encryptForm,
|
||||
uid: localStorage.data
|
||||
};
|
||||
$http
|
||||
.post($url.changePassword, data)
|
||||
.then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
localStorage.clear();
|
||||
window.location.reload();
|
||||
} else {
|
||||
ElMessage.error("密码修改失败!");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
149
src/components/manager/unbind.vue
Normal file
149
src/components/manager/unbind.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ close, titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
解绑
|
||||
</div>
|
||||
<div
|
||||
@click="close"
|
||||
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"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="IMSI 号" prop="card_imsi">
|
||||
<el-input
|
||||
minlength="18"
|
||||
maxlength="18"
|
||||
clearable
|
||||
placeholder="请输入 IMSI 号"
|
||||
v-model="ruleForm.card_imsi"
|
||||
@input="filter(ruleForm.card_imsi, 'card_imsi')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="unbind(ruleFormRef)">
|
||||
解绑
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const ruleFormRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
card_imsi: "",
|
||||
});
|
||||
|
||||
const rules = reactive({
|
||||
card_imsi: [
|
||||
{ required: true, message: "请输入 IMSI 号", trigger: "blur" },
|
||||
{ min: 18, max: 18, message: "输入长度应当为 18 位", trigger: "change" },
|
||||
],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["unBindCard", "disconnect"]);
|
||||
|
||||
const props = defineProps({
|
||||
card_id: String,
|
||||
});
|
||||
|
||||
const filter = (value, label) => {
|
||||
let filterValue = value.replace(/\D/g, "");
|
||||
if (label == "card_imsi") {
|
||||
ruleForm.card_imsi = filterValue;
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const resetForm = (formEl) => {
|
||||
dialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
|
||||
const unbind = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
dialogVisible.value = false;
|
||||
const data = {
|
||||
card_id: props.card_id,
|
||||
card_imsi: ruleForm.card_imsi,
|
||||
};
|
||||
$http.post($url.unBindCard, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
ElMessage({
|
||||
message: "解绑成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("unBindCard");
|
||||
ruleForm.card_imsi = "";
|
||||
emit("disconnect");
|
||||
window.location.reload();
|
||||
} else {
|
||||
ElMessage.error("解绑失败!");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
|
||||
watch(dialogVisible, (value) => {
|
||||
if (!value) {
|
||||
resetForm(ruleFormRef.value);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user