修改数据填报,添加鱼种类下载按钮增加延迟时间5分钟,登录添加记住密码
This commit is contained in:
parent
fb582add0f
commit
24d56e2944
@ -9,6 +9,6 @@ VITE_APP_BASE_API = '/dev-api'
|
||||
## 开发环境API地址
|
||||
# VITE_APP_BASE_URL = 'http://localhost:8093'
|
||||
VITE_APP_BASE_URL = 'http://10.84.121.21:8093'
|
||||
VITE_APP_BASE_API_URL = 'https://211.99.26.225:12130/prod-api'
|
||||
VITE_APP_BASE_API_URL = 'http://10.84.121.21:8093'
|
||||
## 开发环境预览 图片视频地址
|
||||
VITE_APP_PREVIEW_URL = 'https://211.99.26.225:12125'
|
||||
|
||||
BIN
frontend/public/file/鱼种类字典数据.xlsx
Normal file
BIN
frontend/public/file/鱼种类字典数据.xlsx
Normal file
Binary file not shown.
12
frontend/src/components/MapModal/components/BasicInfo.vue
Normal file
12
frontend/src/components/MapModal/components/BasicInfo.vue
Normal file
@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
基本信息
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue';
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
生态流量
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue';
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
生态流量泄放设施
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue';
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
全景影像
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue';
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
电站监测数据
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue';
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
12
frontend/src/components/MapModal/components/SsspLayer.vue
Normal file
12
frontend/src/components/MapModal/components/SsspLayer.vue
Normal file
@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
视频
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue';
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
阶段属性
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue';
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
预警提示
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue';
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
119
frontend/src/components/MapModal/index.vue
Normal file
119
frontend/src/components/MapModal/index.vue
Normal file
@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:open="visible"
|
||||
:title="title"
|
||||
width="800px"
|
||||
:footer="null"
|
||||
:closable="true"
|
||||
@cancel="handleClose"
|
||||
class="map-modal"
|
||||
>
|
||||
<div class="map-modal-content">
|
||||
<a-tabs v-model:activeKey="currentActiveKey">
|
||||
<a-tab-pane
|
||||
v-for="tab in tabsConfig"
|
||||
:key="tab.key"
|
||||
:tab="tab.title"
|
||||
>
|
||||
<!-- 根据 key 动态渲染子组件 -->
|
||||
<div v-if="currentActiveKey === 'basicInfo'" class="tab-pane-container">
|
||||
<!-- 假设 BasicInfo 是预定义的组件 -->
|
||||
<BasicInfo :data="modalData" />
|
||||
</div>
|
||||
|
||||
<div v-else-if="currentActiveKey === 'mapView'" class="tab-pane-container">
|
||||
<!-- 假设 MapView 是预定义的组件 -->
|
||||
<MapView :data="modalData" />
|
||||
</div>
|
||||
|
||||
<div v-else-if="currentActiveKey === 'surrounding'" class="tab-pane-container">
|
||||
<!-- 其他预定义组件 -->
|
||||
<SurroundingInfo :data="modalData" />
|
||||
</div>
|
||||
|
||||
<div v-else class="empty-placeholder">
|
||||
未找到对应 Key ({{ currentActiveKey }}) 的组件配置
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue';
|
||||
// 导入预定义的 Tab 内容组件
|
||||
// 请根据实际路径调整导入地址
|
||||
import BasicInfo from './components/BasicInfo.vue';
|
||||
import MapView from './components/MapView.vue';
|
||||
import SurroundingInfo from './components/SurroundingInfo.vue';
|
||||
|
||||
// 定义 Tab 配置项接口
|
||||
interface TabItem {
|
||||
key: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
// 定义 Props
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
title?: string;
|
||||
activeKey?: string; // 外部控制的当前激活 tab
|
||||
tabsConfig?: TabItem[]; // Tab 配置列表,用于生成 Tab 头
|
||||
data?: any; // 可选:传递给内部组件的数据
|
||||
}>();
|
||||
|
||||
// 定义 Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:visible', value: boolean): void;
|
||||
(e: 'change', key: string): void; // 当 tab 切换时触发
|
||||
}>();
|
||||
|
||||
// 内部维护的 activeKey
|
||||
const currentActiveKey = ref<string>(props.activeKey || '');
|
||||
|
||||
// 监听外部传入的 activeKey 变化
|
||||
watch(() => props.activeKey, (newVal) => {
|
||||
if (newVal) {
|
||||
currentActiveKey.value = newVal;
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
// 监听内部 tab 切换,通知父组件
|
||||
watch(currentActiveKey, (newVal) => {
|
||||
emit('change', newVal);
|
||||
});
|
||||
|
||||
// 关闭弹窗
|
||||
const handleClose = () => {
|
||||
emit('update:visible', false);
|
||||
};
|
||||
|
||||
// 为了方便模板中使用,将 props.data 暴露给模板
|
||||
const modalData = ref(props.data);
|
||||
watch(() => props.data, (newVal) => {
|
||||
modalData.value = newVal;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.map-modal {
|
||||
:deep(.ant-modal-body) {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.map-modal-content {
|
||||
min-height: 300px; // 增加高度以容纳内容
|
||||
|
||||
.tab-pane-container {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.empty-placeholder {
|
||||
color: #999;
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
1312
frontend/src/components/MapModal/setting.config.ts
Normal file
1312
frontend/src/components/MapModal/setting.config.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,11 +2,12 @@ import axios from 'axios';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import router from '@/router';
|
||||
|
||||
// 创建 axios 实例
|
||||
const service = axios.create({
|
||||
baseURL: import.meta.env.VITE_APP_BASE_API,
|
||||
timeout: 100000,
|
||||
timeout: 300000, // 5分钟
|
||||
headers: { 'Content-Type': 'application/json;charset=utf-8' }
|
||||
});
|
||||
|
||||
@ -63,6 +64,7 @@ service.interceptors.response.use(
|
||||
cancelButtonProps: { disabled: false },
|
||||
onOk: () => {
|
||||
localStorage.clear();
|
||||
router.push('/login');
|
||||
window.location.href = '/';
|
||||
},
|
||||
});
|
||||
|
||||
@ -114,13 +114,14 @@
|
||||
<span>登录</span>
|
||||
</a-button>
|
||||
<div style="width: 100%;display: flex;align-items: center;justify-content: space-between;">
|
||||
<a-button type="link" size="mini" block @click="showForgotPasswordPage"
|
||||
<a-checkbox v-model:checked="remember" style="margin-top: 10px;">记住密码</a-checkbox>
|
||||
<a-button type="link" size="mini" @click="showForgotPasswordPage"
|
||||
:style="{ marginTop: '10px', border: 'none' }">
|
||||
忘记密码
|
||||
</a-button>
|
||||
<a-button type="link" size="mini" block @click="goRegister"
|
||||
<a-button type="link" size="mini" @click="goRegister"
|
||||
:style="{ marginTop: '10px', border: 'none' }">
|
||||
注册
|
||||
用户注册
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
@ -188,6 +189,7 @@ import { UserOutlined, LockOutlined, MobileOutlined } from "@ant-design/icons-vu
|
||||
import { getCaptcha, sendSmsCode, smsLoginApi, resetPassword } from "@/api/auth";
|
||||
import { message } from "ant-design-vue";
|
||||
import { setToken } from "@/utils/auth";
|
||||
import Cookies from "js-cookie";
|
||||
// 组件依赖
|
||||
|
||||
import router from "@/router";
|
||||
@ -367,10 +369,19 @@ function onFinish() {
|
||||
if (user.password !== state.cookiePass) {
|
||||
user.password = encrypt(user.password);
|
||||
}
|
||||
console.log(user);
|
||||
userStore
|
||||
.login(user)
|
||||
.then(() => {
|
||||
if (remember.value == true) {
|
||||
Cookies.set('username', user.username, { expires: 30 });
|
||||
Cookies.set('password', user.password, { expires: 30 });
|
||||
Cookies.set('rememberMe', String(remember.value), { expires: 30 });
|
||||
} else {
|
||||
// 如果用户取消勾选记住密码,应该移除 cookie
|
||||
Cookies.remove('username');
|
||||
Cookies.remove('password');
|
||||
Cookies.remove('rememberMe');
|
||||
}
|
||||
router.push({ path: "/" });
|
||||
state.loading = false;
|
||||
message.success("登录成功");
|
||||
@ -492,6 +503,22 @@ function getOtherQuery(query: any) {
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
function getCookie() {
|
||||
const username = Cookies.get("username");
|
||||
let password = Cookies.get("password");
|
||||
const rememberMe = Cookies.get("rememberMe");
|
||||
rememberMe == "true" ? (remember.value = Boolean(rememberMe)) : false;
|
||||
// 保存cookie里面的加密后的密码
|
||||
state.cookiePass = password === undefined ? "" : password;
|
||||
password = password === undefined ? state.loginData.password : password;
|
||||
state.loginData = {
|
||||
username: username === undefined ? state.loginData.username : username,
|
||||
password: decrypt(password),
|
||||
code: "",
|
||||
uuid: "",
|
||||
};
|
||||
remember.value = rememberMe === undefined ? false : Boolean(rememberMe);
|
||||
}
|
||||
function getCode() {
|
||||
getCaptcha().then((result: any) => {
|
||||
codeUrl.value = result.data.img;
|
||||
@ -736,6 +763,7 @@ const handleResetPassword = async () => {
|
||||
|
||||
onMounted(() => {
|
||||
getCode();
|
||||
getCookie();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@ -268,7 +268,7 @@
|
||||
v-if="!isView"
|
||||
v-model:file-list="videoFileList"
|
||||
list-type="text"
|
||||
:multiple="false"
|
||||
:multiple="true"
|
||||
accept=".mp4"
|
||||
:before-upload="beforeVideoUpload"
|
||||
@preview="handleVideoPreview"
|
||||
@ -566,7 +566,14 @@ const handleImageRemove = (file: any) => {
|
||||
|
||||
// 移除视频
|
||||
const handleVideoRemove = (file: any) => {
|
||||
videoFileList.value = [];
|
||||
// 找到该文件在列表中的索引
|
||||
const index = videoFileList.value.indexOf(file);
|
||||
if (index > -1) {
|
||||
// 创建新数组并移除该项
|
||||
const newFileList = videoFileList.value.slice();
|
||||
newFileList.splice(index, 1);
|
||||
videoFileList.value = newFileList;
|
||||
}
|
||||
};
|
||||
// 1. 定义一个初始化表单的函数
|
||||
const initForm = () => {
|
||||
|
||||
@ -62,7 +62,9 @@
|
||||
</a-tooltip> -->
|
||||
<a-tooltip title="鱼种类字典数据下载">
|
||||
<a-button>
|
||||
<a href="/file/鱼种类字典数据.xlsx" download="鱼种类字典数据.xlsx">
|
||||
鱼种类字典数据下载
|
||||
</a>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip title="操作手册下载">
|
||||
|
||||
@ -159,7 +159,7 @@
|
||||
<a-form-item label="选中记录数">
|
||||
<span>{{ selectedRows.length }} 条</span>
|
||||
</a-form-item>
|
||||
<a-form-item label="审批意见" required>
|
||||
<a-form-item label="审批意见">
|
||||
<a-textarea v-model:value="batchApproveForm.approveComment" :rows="4" placeholder="请输入审批意见(必填)"
|
||||
:maxlength="500" show-count />
|
||||
</a-form-item>
|
||||
@ -668,6 +668,9 @@ const handleShowApprovalLog = (record: any) => {
|
||||
dataType: "string",
|
||||
value: record.id,
|
||||
}
|
||||
],
|
||||
sort:[
|
||||
{ field: "operateTime", order: "desc" }
|
||||
]
|
||||
};
|
||||
approvalLogTableRef.value?.getList(filter);
|
||||
@ -835,10 +838,10 @@ const handleBatchApprove = () => {
|
||||
// 确认批量审批
|
||||
const handleBatchApproveConfirm = async () => {
|
||||
// 验证审批意见
|
||||
if (!batchApproveForm.value.approveComment || batchApproveForm.value.approveComment.trim() === '') {
|
||||
message.warning('请填写审批意见');
|
||||
return;
|
||||
}
|
||||
// if (!batchApproveForm.value.approveComment || batchApproveForm.value.approveComment.trim() === '') {
|
||||
// message.warning('请填写审批意见');
|
||||
// return;
|
||||
// }
|
||||
|
||||
// 检查是否有已通过的记录
|
||||
const hasApprovedRecord = selectedRows.value.some(row => row.status != 'PENDING');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user