更新代码

This commit is contained in:
2026-09-15 10:44:31 +08:00
parent 9875832019
commit 943c3708b0
125 changed files with 2009 additions and 1728 deletions
+1 -6
View File
@@ -120,6 +120,7 @@ import { User, SwitchButton, Sunny, Moon, Refresh, Bell, HomeFilled, Loading, Me
import { ElMessage } from 'element-plus';
import { getMySiteReminders, readAllSiteReminders } from "@/api/sitereminder";
import MessageDetailDialog from "./MessageDetailDialog.vue";
import { formatTime } from "@/utils/datetime";
const router = useRouter();
const route = useRoute();
@@ -181,12 +182,6 @@ const loadingMessages = ref(false);
const detailVisible = ref(false);
const currentReminder = ref<any>({});
const formatTime = (timeStr: any) => {
if (!timeStr) return "-";
const date = new Date(timeStr);
return date.toLocaleString();
};
const fetchUnreadCount = async () => {
if (!authStore.token) return;
try {
@@ -32,6 +32,7 @@
import { computed, ref, watch } from "vue";
import { User, Calendar } from "@element-plus/icons-vue";
import { readSiteReminder } from "@/api/sitereminder";
import { formatTime } from "@/utils/datetime";
const props = defineProps({
modelValue: Boolean,
@@ -62,12 +63,6 @@ const getSenderName = (item: any) => {
return item.sender_type;
};
const formatTime = (timeStr: any) => {
if (!timeStr) return "-";
const date = new Date(timeStr);
return date.toLocaleString();
};
watch(() => props.modelValue, async (val) => {
if (val && props.reminder && !props.viewOnly && props.reminder.is_read === 0) {
loading.value = true;
+55
View File
@@ -0,0 +1,55 @@
/**
* 统一日期时间格式化工具(backend 端)
*
* 后端(Go)返回的时间字段为 RFC3339 / ISO 8601 字符串,
* 例如 "2026-03-31T23:34:07+08:00",直接渲染不友好。
* 页面上显示时间统一使用本工具,输出:
* formatDateTime / formatTime -> 2026-03-31 23:34:07(YYYY-MM-DD HH:mm:ss)
* formatDate / formatDateOnly -> 2026-03-31(YYYY-MM-DD)
*/
const pad = (n: number) => String(n).padStart(2, "0");
function toDate(value: any): Date | null {
if (value === null || value === undefined || value === "") return null;
if (value instanceof Date) return isNaN(value.getTime()) ? null : value;
// 兼容秒级 / 毫秒级时间戳
if (typeof value === "number") {
const d = new Date(value < 1e12 ? value * 1000 : value);
return isNaN(d.getTime()) ? null : d;
}
// "2026-03-31 23:34:07" 形式在部分浏览器解析异常,统一先替换为 ISO 形式
const str = String(value).trim().replace(" ", "T");
const d = new Date(str);
return isNaN(d.getTime()) ? null : d;
}
/** 2026-03-31 23:34:07(YYYY-MM-DD HH:mm:ss);非法值返回 "-" */
export function formatDateTime(value: any): string {
const d = toDate(value);
if (!d) return "-";
return (
`${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ` +
`${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
);
}
/** 与 formatDateTime 相同(兼容旧调用名) */
export function formatTime(value: any): string {
return formatDateTime(value);
}
/** 2026-03-31(YYYY-MM-DD);非法值返回 "-";纯日期串不做时区换算 */
export function formatDate(value: any): string {
if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}$/.test(value.trim())) {
return value.trim();
}
const d = toDate(value);
if (!d) return "-";
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
}
/** 与 formatDate 相同(兼容旧调用名) */
export function formatDateOnly(value: any): string {
return formatDate(value);
}
@@ -30,7 +30,7 @@
</span>
<span class="meta-item">
<i class="el-icon-view"></i>
创建日期:{{ model?.create_time }}
创建日期:{{ formatDateTime(model?.create_time) }}
</span>
</div>
</div>
@@ -52,6 +52,7 @@
<script lang="ts" setup>
import { ref, watch, onMounted } from "vue";
import { listCategories } from "@/api/article";
import { formatDateTime } from "@/utils/datetime";
import { ElMessage, ElMessageBox } from "element-plus";
const categoryOptions = ref([]);
@@ -117,8 +117,12 @@
width="100"
align="center"
/>
<el-table-column prop="publish_date" label="发布时间" width="160" />
<el-table-column prop="update_time" label="更新时间" width="160" />
<el-table-column prop="publish_date" label="发布时间" width="160">
<template #default="{ row }">{{ formatDate(row.publish_date) }}</template>
</el-table-column>
<el-table-column prop="update_time" label="更新时间" width="160">
<template #default="{ row }">{{ formatDateTime(row.update_time) }}</template>
</el-table-column>
<el-table-column prop="publisher" label="发布人" width="120" />
<el-table-column label="操作" width="260" fixed="right" align="center">
<template #default="{ row }">
@@ -215,6 +219,7 @@ import { ElMessage, ElMessageBox } from "element-plus";
import { Search } from "@element-plus/icons-vue";
import Edit from "./components/edit.vue";
import Preview from "./components/preview.vue";
import { formatDate, formatDateTime } from "@/utils/datetime";
import { useAuthStore } from "@/stores/auth";
import {
listArticles,
+4 -1
View File
@@ -63,7 +63,9 @@
</el-tag>
</template>
</el-table-column>
<el-table-column prop="create_time" label="创建时间" width="180" />
<el-table-column prop="create_time" label="创建时间" width="180">
<template #default="{ row }">{{ formatDateTime(row.create_time) }}</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right">
<template #default="scope">
<el-button size="small" @click="handleEdit(scope.row)"
@@ -108,6 +110,7 @@ import { ref, reactive, onMounted } from "vue";
import { Plus, Refresh } from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox } from "element-plus";
import Edit from "./components/edit.vue";
import { formatDateTime } from "@/utils/datetime";
import { getDemandList, deleteDemand } from "@/api/demand";
// 状态管理
+4 -1
View File
@@ -76,7 +76,9 @@
<el-tag v-else :type="sslTagType(scope.row.ssl_status)">{{ sslText(scope.row.ssl_status) }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="create_time" label="申请时间" width="170" />
<el-table-column prop="create_time" label="申请时间" width="170">
<template #default="{ row }">{{ formatDateTime(row.create_time) }}</template>
</el-table-column>
<el-table-column label="操作" width="230" fixed="right" align="center">
<template #default="scope">
<!-- 自有域名无人工审核:解析与证书就绪后自动生效,这里只提供重新检测与禁用 -->
@@ -134,6 +136,7 @@
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Refresh } from '@element-plus/icons-vue'
import { formatDateTime } from '@/utils/datetime'
import {
getTenantDomainList,
auditTenantDomain,
+4 -1
View File
@@ -49,7 +49,9 @@
</el-tag>
</template>
</el-table-column>
<el-table-column prop="create_time" label="创建时间" width="180" />
<el-table-column prop="create_time" label="创建时间" width="180">
<template #default="{ row }">{{ formatDateTime(row.create_time) }}</template>
</el-table-column>
<el-table-column label="操作" width="240" fixed="right" align="center">
<template #default="scope">
<el-button size="small" text @click="handleEdit(scope.row)">
@@ -107,6 +109,7 @@
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Edit, Delete, Refresh, Switch } from '@element-plus/icons-vue'
import { formatDateTime } from '@/utils/datetime'
import {
getDomainPoolList,
createDomainPool,
@@ -81,7 +81,9 @@
/>
</template>
</el-table-column>
<el-table-column prop="create_time" label="创建时间" width="180" align="center" />
<el-table-column prop="create_time" label="创建时间" width="180" align="center">
<template #default="{ row }">{{ formatDateTime(row.create_time) }}</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)">
@@ -130,6 +132,7 @@ import {
deleteFriendlink
} from '@/api/friendlink'
import EditDialog from './components/edit.vue'
import { formatDateTime } from '@/utils/datetime'
// @ts-ignore
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
@@ -60,7 +60,9 @@
<el-table-column prop="desc" label="产品描述" min-width="150" align="center" />
<el-table-column prop="url" label="跳转地址" min-width="150" align="center" />
<el-table-column prop="sort" label="排序" width="80" align="center" />
<el-table-column prop="create_time" label="创建时间" width="180" align="center" />
<el-table-column prop="create_time" label="创建时间" width="180" align="center">
<template #default="{ row }">{{ formatDateTime(row.create_time) }}</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)">
@@ -103,6 +105,7 @@ import {
deleteProducts
} from '@/api/products'
import EditDialog from './components/edit.vue'
import { formatDateTime } from '@/utils/datetime'
// @ts-ignore
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
@@ -40,7 +40,9 @@
<el-table-column prop="desc" label="分类描述" min-width="200" align="center" />
<el-table-column prop="pid" label="父级ID" width="110" align="center" />
<el-table-column prop="sort" label="排序" width="90" align="center" />
<el-table-column prop="create_time" label="创建时间" min-width="180" align="center" />
<el-table-column prop="create_time" label="创建时间" min-width="180" align="center">
<template #default="{ row }">{{ formatDateTime(row.create_time) }}</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)">
@@ -81,6 +83,7 @@
deleteProductsTypes
} from '@/api/products'
import EditDialog from './components/edit.vue'
import { formatDateTime } from '@/utils/datetime'
// 加载状态
const loading = ref(false)
@@ -65,7 +65,9 @@
<el-table-column prop="desc" label="方案描述" min-width="150" align="center" />
<el-table-column prop="url" label="跳转地址" min-width="150" align="center" />
<el-table-column prop="sort" label="排序" width="80" align="center" />
<el-table-column prop="create_time" label="创建时间" width="180" align="center" />
<el-table-column prop="create_time" label="创建时间" width="180" align="center">
<template #default="{ row }">{{ formatDateTime(row.create_time) }}</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)">
@@ -108,6 +110,7 @@ import {
deleteService
} from '@/api/services'
import EditDialog from './components/edit.vue'
import { formatDateTime } from '@/utils/datetime'
// @ts-ignore
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
@@ -40,7 +40,9 @@
<el-table-column prop="desc" label="分类描述" min-width="200" align="center" />
<el-table-column prop="pid" label="父级ID" width="110" align="center" />
<el-table-column prop="sort" label="排序" width="90" align="center" />
<el-table-column prop="create_time" label="创建时间" min-width="180" align="center" />
<el-table-column prop="create_time" label="创建时间" min-width="180" align="center">
<template #default="{ row }">{{ formatDateTime(row.create_time) }}</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)">
@@ -81,6 +83,7 @@ import {
deleteServicesTypes
} from '@/api/services'
import EditDialog from './components/edit.vue'
import { formatDateTime } from '@/utils/datetime'
// 加载状态
const loading = ref(false)
@@ -91,7 +91,7 @@
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="创建时间">
{{ contact.create_time || '-' }}
{{ contact.create_time ? formatDateTime(contact.create_time) : '-' }}
</el-descriptions-item>
</el-descriptions>
</div>
@@ -108,6 +108,7 @@
<script setup>
import { computed } from 'vue'
import { formatDateTime } from '@/utils/datetime'
const props = defineProps({
modelValue: { type: Boolean, default: false },
@@ -299,6 +299,8 @@ import {
import { finishSchedule, getScheduleList, getScheduleStats } from "@/api/oaSchedule";
import ScheduleDetail from "../schedule/components/detail.vue";
import SchedulePostpone from "../schedule/components/postponeDialog.vue";
// 时间显示统一为:YYYY-MM-DD HH:mm:ss
import { formatDateTime } from "@/utils/datetime";
const emptyStat = () => ({ total: 0, paid: 0, unpaid: 0, count: 0 });
const dashboard = reactive({
@@ -607,14 +609,7 @@ const noticeDetailItem = ref(null);
const noticeTypeLabel = (type) => ({ 1: "公告", 2: "活动" }[type] || "通知");
const noticeTypeTag = (type) => ({ 1: "primary", 2: "success" }[type] || "info");
const formatDateTime = (value) => {
if (!value) return "-";
const d = new Date(value);
if (Number.isNaN(d.getTime())) return String(value);
return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())} ${pad2(
d.getHours()
)}:${pad2(d.getMinutes())}`;
};
// 列表右侧时间:今天显示 HH:mm,本年显示 M/D,跨年显示 YYYY-M-D
const noticeTime = (item) => {
@@ -297,6 +297,8 @@ import {
summarizeReceiptAmountRows
} from '../utils/invoiceAmount'
import ItemForm from './itemForm.vue'
// 时间显示统一为:YYYY-MM-DD HH:mm:ss
import { formatDateTime } from '@/utils/datetime'
const props = defineProps({
modelValue: { type: Boolean, default: false },
@@ -913,7 +915,6 @@ const removeReceipt = async receipt => {
const actionLabel = value => ({ 1: '提交申请', 2: '审批通过', 3: '审批驳回', 4: '转审', 5: '撤回' })[value] || '审批操作'
const money = value => Number(value || 0).toFixed(2)
const formatDateTime = value => value ? new Date(value).toLocaleString('zh-CN', { hour12: false }) : '-'
</script>
<style lang="less" scoped>
@@ -169,6 +169,8 @@ import { Plus, Refresh, Search, Setting } from "@element-plus/icons-vue";
import ReimburseEdit from "./components/edit.vue";
import ReimburseDetail from "./components/detail.vue";
import ExpenseTypeDialog from "./components/expenseTypeDialog.vue";
// 日期/时间显示统一格式:YYYY-MM-DD 与 YYYY-MM-DD HH:mm:ss
import { formatDate as formatDateUtil, formatDateTime } from "@/utils/datetime";
import { exportReimbursementPdf } from "./utils/exportReimbursementPdf";
import {
createReimbursement,
@@ -351,15 +353,11 @@ const handleExport = async (row) => {
};
const money = (value) => Number(value || 0).toFixed(2);
const formatDate = (value) => {
// 日期显示统一为:YYYY-MM-DD
const formatDate = (value: any) => {
if (!value) return "-";
const text = String(value);
const match = text.match(/^(\d{4}-\d{2}-\d{2})/);
if (match) return match[1];
return text;
return formatDateUtil(value);
};
const formatDateTime = (value) =>
value ? new Date(value).toLocaleString("zh-CN", { hour12: false }) : "-";
const statusLabel = (value) =>
statusOptions.find((item) => item.value === value)?.label || "未知";
const statusType = (value) =>
@@ -38,10 +38,10 @@
</span>
</el-descriptions-item>
<el-descriptions-item label="创建时间">
{{ roleDetail.create_time }}
{{ formatDateTime(roleDetail.create_time) }}
</el-descriptions-item>
<el-descriptions-item label="更新时间">
{{ roleDetail.update_time }}
{{ formatDateTime(roleDetail.update_time) }}
</el-descriptions-item>
</el-descriptions>
@@ -56,6 +56,7 @@ import { ref, watch, computed } from "vue";
import { ElMessage } from "element-plus";
import { getRoleById } from "@/api/role";
import { getAssignableMenus } from "@/api/menu";
import { formatDateTime } from "@/utils/datetime";
interface Props {
modelValue: boolean;
@@ -19,7 +19,7 @@
<div class="filter-bar">
<el-radio-group v-model="typeFilter">
<el-radio-button :value="'all'">全部</el-radio-button>
<el-radio-button :value="2">租户角色</el-radio-button>
<el-radio-button :value="'global'">全局角色</el-radio-button>
<el-radio-button :value="'custom'">自定义角色</el-radio-button>
</el-radio-group>
</div>
@@ -41,7 +41,9 @@
/>
<el-table-column prop="cid" label="类型" width="150" align="center">
<template #default="{ row }">
<el-tag v-if="row.cid === 1" type="danger" size="small">平台角色</el-tag>
<el-tag v-if="Number(row.tenant_id || 0) === 0" type="success" size="small">
全局角色
</el-tag>
<el-tag v-else-if="Number(row.is_custom) === 1" type="warning" size="small">
自定义角色
</el-tag>
@@ -73,6 +75,7 @@
详情
</el-button>
<el-button
v-if="Number(row.tenant_id || 0) > 0"
size="small"
type="primary"
link
@@ -124,8 +127,9 @@ const loading = ref(false);
const error = ref("");
const typeFilter = ref<string | number>("all");
const displayRoles = computed(() => {
// custom = 本租户自建的自定义角色;2 = 租户角色(含系统预置)
// global = 全局角色(所有租户共用,平台端维护);custom = 本租户自建的自定义角色
if (typeFilter.value === "all") return roles.value;
if (typeFilter.value === "global") return roles.value.filter((r) => Number(r.tenant_id || 0) === 0);
if (typeFilter.value === "custom") return roles.value.filter((r) => Number(r.is_custom) === 1);
return roles.value.filter((r) => Number(r.cid) === Number(typeFilter.value));
});
@@ -36,7 +36,7 @@
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="创建时间">
{{ detailData.create_time || '-' }}
{{ detailData.create_time ? formatDateTime(detailData.create_time) : '-' }}
</el-descriptions-item>
</el-descriptions>
@@ -68,6 +68,7 @@
import { ref } from "vue";
import { getTenantDetail } from "@/api/tenant";
import TenantUsersTab from "./TenantUsersTab.vue";
import { formatDateTime } from "@/utils/datetime";
const visible = ref(false);
const loading = ref(false);
@@ -90,7 +90,9 @@
</el-tag>
</template>
</el-table-column>
<el-table-column prop="create_time" label="申请时间" width="170" />
<el-table-column prop="create_time" label="申请时间" width="170">
<template #default="{ row }">{{ formatDateTime(row.create_time) }}</template>
</el-table-column>
<el-table-column label="操作" width="230" fixed="right" align="center">
<template #default="scope">
<el-button
@@ -238,6 +240,7 @@
import { ref, reactive, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Plus, Link } from "@element-plus/icons-vue";
import { formatDateTime } from "@/utils/datetime";
import {
getMyDomains,
applyTenantDomain,
@@ -48,10 +48,10 @@
{{ user.login_count || 0 }}
</el-descriptions-item>
<el-descriptions-item label="创建时间">
{{ user.create_time || "未知" }}
{{ user.create_time ? formatDateTime(user.create_time) : "未知" }}
</el-descriptions-item>
<el-descriptions-item label="更新时间" :span="2">
{{ user.update_time || "未知" }}
{{ user.update_time ? formatDateTime(user.update_time) : "未知" }}
</el-descriptions-item>
</el-descriptions>
</div>
@@ -66,6 +66,7 @@
import { ref, watch } from "vue";
import { UserFilled } from "@element-plus/icons-vue";
import { getAllRoles } from "@/api/role";
import { formatDateTime } from "@/utils/datetime";
interface User {
id: number;
@@ -71,7 +71,7 @@
</el-select>
</el-form-item>
<!-- 角色(关联 yz_system_admin_role, cid=2) -->
<!-- 角色(关联 yz_system_admin_role, cid=2):平台默认角色 + 租户自定义角色 -->
<el-form-item label="角色">
<el-select
v-model="form.group_id"
@@ -79,12 +79,22 @@
clearable
style="width: 100%"
>
<el-option
v-for="role in roles"
:key="role.id"
:label="role.name"
:value="role.id"
/>
<el-option-group v-if="globalRoles.length" label="平台默认角色">
<el-option
v-for="role in globalRoles"
:key="role.id"
:label="role.name"
:value="role.id"
/>
</el-option-group>
<el-option-group v-if="customRoles.length" label="租户自定义角色">
<el-option
v-for="role in customRoles"
:key="role.id"
:label="role.name"
:value="role.id"
/>
</el-option-group>
</el-select>
</el-form-item>
</el-form>
@@ -142,6 +152,7 @@ interface RoleOption {
id: number;
name: string;
status?: number;
tenant_id?: number;
}
const roles = ref<RoleOption[]>([]);
@@ -155,6 +166,15 @@ const fetchRoles = async () => {
}
};
// 平台规定的默认角色(全局角色,tenant_id=0,平台端统一维护)
const globalRoles = computed(() =>
roles.value.filter((r) => Number(r.tenant_id || 0) === 0)
);
// 租户自己建立的角色(tenant_id=当前租户)
const customRoles = computed(() =>
roles.value.filter((r) => Number(r.tenant_id || 0) > 0)
);
const dialogTitle = computed(() => {
return isAdd.value ? "添加用户" : "编辑用户";
});
@@ -100,6 +100,8 @@ import { Plus, Edit, Delete } from "@element-plus/icons-vue";
import type { FormInstance, FormRules } from "element-plus";
import { getModuleCategory,editModuleCategory } from "@/api/moduleCenter";
// 该页面展示精确到秒的时间:YYYY-MM-DD HH:mm:ss
import { formatDateTime as formatDate } from "@/utils/datetime";
interface Category {
id: number;
@@ -160,16 +162,7 @@ const getStatusType = (status: number) => {
return map[status] || "info";
};
const formatDate = (date: string) => {
if (!date) return "-";
const d = new Date(date);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
const hours = String(d.getHours()).padStart(2, "0");
const minutes = String(d.getMinutes()).padStart(2, "0");
return `${year}-${month}-${day} ${hours}:${minutes}`;
};
const handleCategoryAdd = () => {
isEdit.value = false;
+3 -10
View File
@@ -146,6 +146,8 @@ import type { FormInstance, FormRules } from "element-plus";
import { getModules, getModuleCategory,editModules } from "@/api/moduleCenter";
import CreateModules from "../components/createModules.vue";
import { uploadFile } from '@/api/file.js';
// 该页面展示精确到秒的时间:YYYY-MM-DD HH:mm:ss
import { formatDateTime as formatDate } from "@/utils/datetime";
interface Module {
id: number;
@@ -266,16 +268,7 @@ function handlePictureCardPreview(file: any) {
const formatDate = (date: string) => {
if (!date) return "-";
const d = new Date(date);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
const hours = String(d.getHours()).padStart(2, "0");
const minutes = String(d.getMinutes()).padStart(2, "0");
return `${year}-${month}-${day} ${hours}:${minutes}`;
};
const handleCreate = () => {
createDialogVisible.value = true;
+3 -10
View File
@@ -175,6 +175,8 @@ import { Plus, View, Delete, UploadFilled, Document } from "@element-plus/icons-
import type { FormInstance, FormRules, UploadFile } from "element-plus";
import { getModules, getModuleCategory } from "@/api/moduleCenter";
// 该页面展示精确到秒的时间:YYYY-MM-DD HH:mm:ss
import { formatDateTime as formatDate } from "@/utils/datetime";
interface Publish {
id: number;
@@ -245,16 +247,7 @@ const getStatusType = (status: number) => {
return map[status] || "info";
};
const formatDate = (date: string) => {
if (!date) return "-";
const d = new Date(date);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
const hours = String(d.getHours()).padStart(2, "0");
const minutes = String(d.getMinutes()).padStart(2, "0");
return `${year}-${month}-${day} ${hours}:${minutes}`;
};
const handlePublish = () => {
publishDialogVisible.value = true;
@@ -139,11 +139,12 @@
import { ref, computed, onMounted, onUnmounted } from 'vue';
import { ElMessage } from 'element-plus';
import { InfoFilled, Refresh, DocumentCopy } from '@element-plus/icons-vue';
import { formatDateTime } from '@/utils/datetime';
// 系统信息数据
const loading = ref(false);
const systemInfo = ref<any>({});
const currentTime = ref(new Date().toLocaleString('zh-CN'));
const currentTime = ref(formatDateTime(new Date()));
// API基础地址
const apiBaseUrl = computed(() => {
@@ -251,7 +252,7 @@ async function fetchSystemInfo() {
// 刷新信息
function refreshInfo() {
fetchSystemInfo();
currentTime.value = new Date().toLocaleString('zh-CN');
currentTime.value = formatDateTime(new Date());
ElMessage.success('信息已刷新');
}
@@ -285,7 +286,7 @@ function copySystemInfo() {
- 屏幕分辨率:${clientInfo.value.screenResolution}
- 设备类型:${clientInfo.value.isMobile ? '移动设备' : '桌面设备'}
生成时间:${new Date().toLocaleString('zh-CN')}`;
生成时间:${formatDateTime(new Date())}`;
if (navigator.clipboard) {
navigator.clipboard.writeText(infoText).then(() => {
@@ -315,7 +316,7 @@ onMounted(() => {
fetchSystemInfo();
// 每秒更新时间
timeInterval = setInterval(() => {
currentTime.value = new Date().toLocaleString('zh-CN');
currentTime.value = formatDateTime(new Date());
}, 1000);
});
@@ -216,21 +216,13 @@
{ immediate: true }
)
// 格式化日期
// 日期显示统一为:YYYY-MM-DD HH:mm:ss
function formatDate(dateStr: string | null | undefined): string {
if (!dateStr) return ''
try {
const date = new Date(dateStr)
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
})
} catch {
return dateStr as string
}
const d = new Date(dateStr)
if (isNaN(d.getTime())) return String(dateStr)
const p = (n: number) => String(n).padStart(2, '0')
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`
}
// 获取字典类型列表(用于下拉选择)
@@ -156,21 +156,13 @@
return result
})
// 格式化日期
// 日期显示统一为:YYYY-MM-DD HH:mm:ss
function formatDate(dateStr: string | null | undefined): string {
if (!dateStr) return ''
try {
const date = new Date(dateStr)
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
})
} catch {
return dateStr as string
}
const d = new Date(dateStr)
if (isNaN(d.getTime())) return String(dateStr)
const p = (n: number) => String(n).padStart(2, '0')
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`
}
// 获取字典类型列表
+3 -14
View File
@@ -149,6 +149,7 @@ import {
} from '@/api/dict'
import DictTypeEdit from './components/DictTypeEdit.vue'
import DictItemList from './components/DictItemList.vue'
import { formatDateTime } from '@/utils/datetime'
const currentView = ref<'types' | 'items'>('types')
const typeLoading = ref(false)
@@ -172,21 +173,9 @@ const selectedDictType = computed(() => {
return dictTypes.value.find((type) => type.id === selectedDictTypeId.value) || null
})
// 格式化日期
// 日期显示统一为:YYYY-MM-DD HH:mm:ss(utils/datetime)
function formatDate(dateStr: string | null | undefined): string {
if (!dateStr) return ''
try {
const date = new Date(dateStr)
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
})
} catch {
return dateStr as string
}
return dateStr ? formatDateTime(dateStr) : ''
}
// 获取字典类型列表
@@ -496,6 +496,8 @@ import UploadFile from "./components/uploadFile.vue";
import MoveFile from "./components/moveFile.vue";
import RenameCategory from "./components/renameCategory.vue";
import CreateCategory from "./components/createCategory.vue";
// 日期显示统一为:YYYY-MM-DD
import { formatDate } from "@/utils/datetime";
// 分组相关
interface Group {
@@ -872,14 +874,7 @@ const formatFileSize = (bytes: number): string => {
};
// 格式化日期
const formatDate = (dateStr: string): string => {
const date = new Date(dateStr);
return date.toLocaleDateString("zh-CN", {
year: "numeric",
month: "2-digit",
day: "2-digit",
});
};
// 文件操作
const handleFileClick = (file: FileItem) => {
+4 -6
View File
@@ -124,12 +124,9 @@
show-overflow-tooltip
/>
<el-table-column prop="ip" label="IP地址" width="130" align="center" />
<el-table-column
prop="create_time"
label="登录时间"
width="180"
align="center"
/>
<el-table-column prop="create_time" label="登录时间" width="180" align="center">
<template #default="{ row }">{{ formatDateTime(row.create_time) }}</template>
</el-table-column>
<el-table-column label="操作" width="120" align="center" fixed="right">
<template #default="scope">
<el-button
@@ -192,6 +189,7 @@ import {
batchDeleteLoginLogs,
} from "@/api/loginLog";
import DetailDialog from "./components/detail.vue";
import { formatDateTime } from "@/utils/datetime";
interface LoginLog {
id: number;
@@ -117,12 +117,9 @@
</el-tag>
</template>
</el-table-column>
<el-table-column
prop="create_time"
label="操作时间"
width="180"
align="center"
/>
<el-table-column prop="create_time" label="操作时间" width="180" align="center">
<template #default="{ row }">{{ formatDateTime(row.create_time) }}</template>
</el-table-column>
<el-table-column label="操作" width="120" align="center" fixed="right">
<template #default="scope">
<el-button
@@ -170,6 +167,7 @@ import {
getOperationStatistics,
} from "@/api/operationLog";
import DetailDialog from "./components/detail.vue";
import { formatDateTime } from "@/utils/datetime";
interface OperationLog {
id: number;
+2 -5
View File
@@ -77,6 +77,7 @@ import { ElMessage, ElMessageBox } from 'element-plus';
import { Plus, Search, Delete, MoreFilled } from '@element-plus/icons-vue';
import NoteEditor from './components/edit.vue';
import { getNotebookList, deleteNotebook } from '@/api/notebook';
import { formatDate } from '@/utils/datetime';
const searchKeyword = ref('');
const currentNoteId = ref(null);
@@ -117,11 +118,7 @@ const formatTime = (dateStr) => {
} else if (diff < 7 * day) {
return `${Math.floor(diff / day)} 天前`;
} else {
return date.toLocaleDateString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
});
return formatDate(date);
}
};
+3 -10
View File
@@ -61,6 +61,8 @@ import { useRouter } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
import { getUserInfo } from "@/api/user";
import { useAuthStore } from "@/stores/auth";
// 该页面展示精确到秒的时间:YYYY-MM-DD HH:mm:ss
import { formatDateTime as formatDate } from "@/utils/datetime";
import ProfileCard from "./components/ProfileCard.vue";
import QuickActions from "./components/QuickActions.vue";
import DetailCard from "./components/DetailCard.vue";
@@ -79,16 +81,7 @@ const passwordDialogVisible = ref(false);
const bindPhoneDialogVisible = ref(false);
const bindEmailDialogVisible = ref(false);
const formatDate = (date) => {
if (!date) return "-";
const d = new Date(date);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
const hours = String(d.getHours()).padStart(2, "0");
const minutes = String(d.getMinutes()).padStart(2, "0");
return `${year}-${month}-${day} ${hours}:${minutes}`;
};
const getSexText = (sex) => {
const map = {