Commit 4ff0ebd7 by Neo Turing

chore: 统一文件行尾符格式为CRLF (Windows)

parent c6c25559
......@@ -28,9 +28,9 @@ export const chineseMessages = {
'@typescript-eslint/prefer-nullish-coalescing': '应使用空值合并运算符',
// 代码风格规则
'indent': '缩进不正确',
'quotes': '引号使用不一致',
'semi': '缺少分号',
indent: '缩进不正确',
quotes: '引号使用不一致',
semi: '缺少分号',
'comma-dangle': '尾随逗号使用不正确',
'eol-last': '文件末尾应有换行符',
'no-trailing-spaces': '行尾存在多余空格',
......
......@@ -9,7 +9,7 @@ export const REG_PHONE =
*
* 6-18 characters, including letters, numbers, and underscores
*/
export const REG_PWD = /^.*$/ // /^\w{6,18}$/;
export const REG_PWD = /^.*$/; // /^\w{6,18}$/;
/** Email reg */
export const REG_EMAIL = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
......
......@@ -2,10 +2,10 @@
import { createReusableTemplate } from '@vueuse/core';
import type { RouteKey } from '@elegant-router/types';
import { h } from 'vue';
import { breadcrumbDark } from 'naive-ui';
import { useThemeStore } from '@/store/modules/theme';
import { useRouteStore } from '@/store/modules/route';
import { useRouterPush } from '@/hooks/common/router';
import { breadcrumbDark } from 'naive-ui';
defineOptions({
name: 'GlobalBreadcrumb'
......
......@@ -20,10 +20,12 @@ withDefaults(defineProps<Props>(), {
<template>
<RouterLink to="/" class="w-full flex-center nowrap-hidden">
<!-- <SystemLogo class="text-32px text-primary" />
<!--
<SystemLogo class="text-32px text-primary" />
<h2 v-show="showTitle" class="pl-8px text-16px text-primary font-bold transition duration-300 ease-in-out">
{{ $t('system.title') }}
</h2> -->
</h2>
-->
<img v-if="Icon" :src="Icon" alt="" style="width: 32px" />
<SystemLogo v-else class="text-32px text-primary" />
<h2 v-show="showTitle" class="pl-8px text-16px text-primary font-bold transition duration-300 ease-in-out">
......
......@@ -70,7 +70,8 @@ function toggleSiderCollapse() {
<i :class="icon"></i>
<p
class="w-full ellipsis-text text-center text-12px transition-height-300"
:class="[isMini ? 'h-0 pt-0' : 'h-20px pt-4px']">
:class="[isMini ? 'h-0 pt-0' : 'h-20px pt-4px']"
>
{{ label }}
</p>
</div>
......
......@@ -104,9 +104,17 @@ registerShortcut();
</script>
<template>
<NModal v-model:show="visible" :segmented="{ footer: 'soft' }" :closable="false" preset="card" auto-focus
footer-style="padding: 0; margin: 0" class="fixed left-0 right-0"
:class="[isMobile ? 'size-full top-0px rounded-0' : 'w-630px top-50px']" @after-leave="handleClose">
<NModal
v-model:show="visible"
:segmented="{ footer: 'soft' }"
:closable="false"
preset="card"
auto-focus
footer-style="padding: 0; margin: 0"
class="fixed left-0 right-0"
:class="[isMobile ? 'size-full top-0px rounded-0' : 'w-630px top-50px']"
@after-leave="handleClose"
>
<NInputGroup>
<NInput v-model:value="keyword" clearable :placeholder="$t('common.keywordSearch')" @input="handleSearch">
<template #prefix>
......
......@@ -11,7 +11,7 @@ defineOptions({
});
const authStore = useAuthStore();
const themeStore = useThemeStore();
themeStore.watermark.text = authStore.userInfo.FullName
themeStore.watermark.text = authStore.userInfo.FullName;
const layoutMode = computed(() => themeStore.layout.mode);
const isMixLayoutMode = computed(() => layoutMode.value.includes('mix'));
......
......@@ -11,7 +11,7 @@ import './plugins/assets';
import { localStg } from '@/utils/storage';
// main.js or main.ts
import 'font-awesome/css/font-awesome.css';
// 引入 KaTeX 样式以支持数学公式渲?import 'katex/dist/katex.min.css';
// 引入 KaTeX 样式以支持数学公式渲?import 'katex/dist/katex.min.css';
import { setupDayjs, setupIconifyOffline, setupLoading, setupNProgress } from './plugins';
import { setupStore } from './store';
import { setupRouter } from './router';
......@@ -48,7 +48,7 @@ import App from './App.vue';
// startInactivityTimer(app);
// }
// 检查认证状?// function checkAuthStatus(app: any) {
// 检查认证状?// function checkAuthStatus(app: any) {
// if (window.uiGlobalConfig?.IsAuthenticated === false) {
// localStg.remove('token');
// localStg.remove('refreshToken');
......@@ -73,16 +73,16 @@ async function setupApp() {
await setupRouter(app);
setupI18n(app);
// 检查认证状? // checkAuthStatus(app);
// 检查认证状? // checkAuthStatus(app);
// 检查上次活动时? // checkLastActivity(app);
// 检查上次活动时? // checkLastActivity(app);
// 监听用户的操? // window.addEventListener('mousemove', () => resetInactivityTimer(app));
// 监听用户的操? // window.addEventListener('mousemove', () => resetInactivityTimer(app));
// window.addEventListener('keydown', () => resetInactivityTimer(app));
// window.addEventListener('click', () => resetInactivityTimer(app));
// window.addEventListener('scroll', () => resetInactivityTimer(app));
// 启动计时? // startInactivityTimer(app);
// 启动计时? // startInactivityTimer(app);
app.use(VueGridLayout);
app.use(MateChat);
......@@ -94,7 +94,7 @@ async function setupApp() {
app.mount('#app');
}
// 页面卸载时保存最后活动时?// window.addEventListener('beforeunload', () => {
// 页面卸载时保存最后活动时?// window.addEventListener('beforeunload', () => {
// localStorage.setItem('lastActivityTime', Date.now().toString());
// });
......
declare module 'vue-grid-layout' {
import { Plugin } from 'vue';
import type { Plugin } from 'vue';
export const GridLayout: any;
export const GridItem: any;
......
......@@ -101,7 +101,8 @@ export const renderMarkdownWithMath = (content: string): string => {
// 处理段落(双换行表示段落分隔)
const paragraphs = processed.split(/\n\s*\n/);
processed = paragraphs.map(paragraph => {
processed = paragraphs
.map(paragraph => {
const trimmed = paragraph.trim();
if (!trimmed) return '';
......@@ -113,7 +114,8 @@ export const renderMarkdownWithMath = (content: string): string => {
// 处理单行换行
const withBreaks = trimmed.replace(/\n/g, '<br>');
return `<p>${withBreaks}</p>`;
}).join('\n');
})
.join('\n');
console.log('最终处理结果:', processed);
return processed;
......
......@@ -7,7 +7,7 @@ export const createMarkdownRenderer = () => {
const md = new MarkdownIt({
html: true,
linkify: true,
typographer: true,
typographer: true
});
// 使用 markdown-it-katex 插件
......@@ -15,7 +15,7 @@ export const createMarkdownRenderer = () => {
blockClass: 'math-display',
errorColor: '#cc0000',
macros: {
"\\RR": "\\mathbb{R}"
'\\RR': '\\mathbb{R}'
}
});
......
<template>
<div class="plan-detail-selector">
<!-- <div class="header">
<div class="title">测试方案明细选择</div>
<n-space style="display: flex; align-items: center;">
<span class="plan-name">{{ planName }}</span>
<n-tag type="info">{{ checkedRowKeys.length }}项已选择</n-tag>
</n-space>
</div> -->
<n-alert type="info" style="margin-bottom: 16px">
请选择需要进行比对测试的项目,选中的项目将被添加到测试数据表格中。
</n-alert>
<n-data-table
:columns="columns"
:data="planDetails"
:bordered="false"
:row-key="(row) => row.key"
:checked-row-keys="checkedRowKeys"
@update:checked-row-keys="handleCheckedRowKeysChange"
:children-key="'children'"
:indent="20"
:max-height="300"
:min-height="300"
:pagination="false"
striped
:loading="loading"
></n-data-table>
<div class="footer">
<n-space justify="end">
<n-button @click="cancel">取消</n-button>
<n-button type="primary" @click="confirm" :disabled="checkedRowKeys.length === 0">
确认选择({{ checkedRowKeys.length }})
</n-button>
</n-space>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, defineEmits, defineProps, ref, watch, onMounted } from 'vue';
import { computed, defineEmits, defineProps, onMounted, ref, watch } from 'vue';
// 主体框架内置的第三方方法通过window对象暴露、供外部组件使用
const axios = (window as any).$axios;
// 获取主题状态
......@@ -161,7 +120,9 @@ function processTreeData(data: any[]) {
}
// 监听standardKvid变化,重新获取数据
watch(() => props.standardKvid, (newValue) => {
watch(
() => props.standardKvid,
newValue => {
if (newValue) {
fetchTestDetails();
// 重置选中状态
......@@ -169,7 +130,9 @@ watch(() => props.standardKvid, (newValue) => {
} else {
planDetails.value = [];
}
}, { immediate: true });
},
{ immediate: true }
);
// 处理行选择变化
function handleCheckedRowKeysChange(keys: (string | number)[]) {
......@@ -185,7 +148,7 @@ const planName = computed(() => {
// 表格列定义
const columns = [
{
type: 'selection',
type: 'selection'
},
{ title: '测试项目', key: 'testItem', align: 'center' },
{ title: '标准值', key: 'standardValue', align: 'center' },
......@@ -283,6 +246,49 @@ onMounted(() => {
});
</script>
<template>
<div class="plan-detail-selector">
<!--
<div class="header">
<div class="title">测试方案明细选择</div>
<n-space style="display: flex; align-items: center;">
<span class="plan-name">{{ planName }}</span>
<n-tag type="info">{{ checkedRowKeys.length }}项已选择</n-tag>
</n-space>
</div>
-->
<NAlert type="info" style="margin-bottom: 16px">
请选择需要进行比对测试的项目,选中的项目将被添加到测试数据表格中。
</NAlert>
<NDataTable
:columns="columns"
:data="planDetails"
:bordered="false"
:row-key="row => row.key"
:checked-row-keys="checkedRowKeys"
children-key="children"
:indent="20"
:max-height="300"
:min-height="300"
:pagination="false"
striped
:loading="loading"
@update:checked-row-keys="handleCheckedRowKeysChange"
></NDataTable>
<div class="footer">
<NSpace justify="end">
<NButton @click="cancel">取消</NButton>
<NButton type="primary" :disabled="checkedRowKeys.length === 0" @click="confirm">
确认选择({{ checkedRowKeys.length }})
</NButton>
</NSpace>
</div>
</div>
</template>
<style scoped>
.plan-detail-selector {
/* padding: 0 0 16px 0; */
......
<script setup lang="ts">
<script setup lang="ts">
import { computed, defineProps, onMounted, reactive, ref, watch, withDefaults } from 'vue';
// 定义Item对象的接口
......@@ -45,7 +45,6 @@ const detailedData = reactive<ItemProps>({});
// 存储原始数据,用于比较是否有变化
const originalData = ref<ItemProps>({});
// 创建一个通用的日期处理函数
const createDateComputed = (getter: () => string | null, setter: (val: string | null) => void) => {
return computed({
......@@ -87,8 +86,6 @@ const createDateComputed = (getter: () => string | null, setter: (val: string |
});
};
// 创建处理后的DealDate计算属性
const formattedDealDate = createDateComputed(
() => detailedData.DealDate,
......@@ -158,8 +155,6 @@ const fetchDetail = async (kvid: string) => {
}
};
// 监听props.item变化,同步到detailedData
watch(
() => props.item,
......@@ -175,10 +170,6 @@ watch(
{ immediate: true, deep: true }
);
// 组件加载时初始化
onMounted(() => {
// console.log('applicationInformation组件已挂载');
......@@ -267,7 +258,6 @@ const createEntity = async () => {
// console.error('创建失败:', response.data);
message.error(response.data?.Message || '创建失败,请重试');
return { success: false, error: response.data?.Message || '创建失败' };
} catch (error) {
// console.error('创建实体失败:', error);
message.error('系统错误,请稍后重试');
......@@ -318,7 +308,6 @@ const updateEntity = async (changedFields: Partial<ItemProps> = {}) => {
// console.error('更新失败:', response.data);
message.error(response.data?.Message || '更新失败,请重试');
return { success: false, error: response.data?.Message || '更新失败' };
} catch (error) {
// console.error('更新实体失败:', error);
message.error('系统错误,请稍后重试');
......@@ -351,7 +340,7 @@ const validateAndSave = async () => {
originalData.value = JSON.parse(JSON.stringify(detailedData));
}
return result.success;
} else {
}
// 有Kvid,检查是否有数据变化
const { changed, changedFields } = hasDataChanged();
......@@ -360,7 +349,7 @@ const validateAndSave = async () => {
// console.log('数据没有变化,无需更新');
message.success('数据已是最新,无需保存');
return true;
} else {
}
// 有变化,需要更新
// console.log('检测到数据变化,执行更新操作,变更字段:', changedFields);
const result = await updateEntity(changedFields);
......@@ -369,8 +358,6 @@ const validateAndSave = async () => {
originalData.value = JSON.parse(JSON.stringify(detailedData));
}
return result.success;
}
}
};
// 导出方法供父组件调用
......@@ -394,12 +381,7 @@ defineExpose({
</div>
<div style="display: flex; width: 100%">
<NFormItem path="SampleName" label="实验室名称" style="width: 50%">
<NInput
v-model:value="detailedData.SampleName"
placeholder="请输入实验室名称"
clearable
size="medium"
/>
<NInput v-model:value="detailedData.SampleName" placeholder="请输入实验室名称" clearable size="medium" />
</NFormItem>
<NFormItem path="labAddress" label="实验室地址" style="width: 50%">
......
<script setup lang="ts">
<script setup lang="ts">
import { computed, defineEmits, defineProps, h, onMounted, ref, resolveComponent } from 'vue';
import TestPlanDetailSelector from './TestPlanDetailSelector.vue'; // '/codes/TestPlanDetailSelector.vue';
......
......@@ -57,14 +57,20 @@ const bgColor = computed(() => {
<NCard :bordered="false" class="relative z-4 w-auto rd-12px">
<div class="w-400px lt-sm:w-300px">
<header class="flex-y-center justify-between">
<img v-if="Icon" :src="Icon" alt="" style="width: 50px;" />
<img v-if="Icon" :src="Icon" alt="" style="width: 50px" />
<SystemLogo v-else class="text-64px text-primary lt-sm:text-48px" />
<h3 class="text-28px text-primary font-500 lt-sm:text-22px">{{ DisplayName }}</h3>
<div class="i-flex-col">
<ThemeSchemaSwitch :theme-schema="themeStore.themeScheme" :show-tooltip="false"
class="text-20px lt-sm:text-18px" @switch="themeStore.toggleThemeScheme" />
<!-- <LangSwitch :lang="appStore.locale" :lang-options="appStore.localeOptions" :show-tooltip="false"
@change-lang="appStore.changeLocale" /> -->
<ThemeSchemaSwitch
:theme-schema="themeStore.themeScheme"
:show-tooltip="false"
class="text-20px lt-sm:text-18px"
@switch="themeStore.toggleThemeScheme"
/>
<!--
<LangSwitch :lang="appStore.locale" :lang-options="appStore.localeOptions" :show-tooltip="false"
@change-lang="appStore.changeLocale" />
-->
</div>
</header>
<main class="pt-24px">
......
......@@ -97,20 +97,24 @@ async function handleSubmit() {
<NButton type="primary" size="large" round block :loading="authStore.loginLoading" @click="handleSubmit">
{{ $t('common.confirm') }}
</NButton>
<!-- <div class="flex-y-center justify-between gap-12px">
<!--
<div class="flex-y-center justify-between gap-12px">
<NButton class="flex-1" block @click="toggleLoginModule('code-login')">
{{ $t(loginModuleRecord['code-login']) }}
</NButton>
<NButton class="flex-1" block @click="toggleLoginModule('register')">
{{ $t(loginModuleRecord.register) }}
</NButton>
</div> -->
<!-- <NDivider class="text-14px text-#666 !m-0">{{ $t('page.login.pwdLogin.otherAccountLogin') }}</NDivider>
</div>
-->
<!--
<NDivider class="text-14px text-#666 !m-0">{{ $t('page.login.pwdLogin.otherAccountLogin') }}</NDivider>
<div class="flex-center gap-12px">
<NButton v-for="item in accounts" :key="item.key" type="primary" @click="handleAccountLogin(item)">
{{ item.label }}
</NButton>
</div> -->
</div>
-->
</NSpace>
</NForm>
</template>
......
......@@ -429,7 +429,7 @@ onUnmounted(() => {
</div>
<div class="header-actions">
<i class="icon-add action-btn" @click="newChat"></i>
<i class="icon-settings action-btn" title="API配置" @click="showConfig = !showConfig"></i>
<i class="action-btn icon-settings" title="API配置" @click="showConfig = !showConfig"></i>
</div>
</div>
......@@ -508,7 +508,7 @@ onUnmounted(() => {
<div v-if="!showStartPage" ref="chatContentRef" class="chat-content">
<template v-for="msg in messages" :key="`${msg.id}-${msg.phase}-${Date.now()}`">
<!-- 用户消息 -->
<div v-if="msg.from === 'user'" class="message user-message">
<div v-if="msg.from === 'user'" class="user-message message">
<div class="message-content">{{ msg.content }}</div>
<div class="message-avatar">👤</div>
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment