批量修改药品编号
Some checks failed
Close stale issues / stale (push) Has been cancelled
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CI / CI OK (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Issue Close Require / close-issues (push) Has been cancelled
Some checks failed
Close stale issues / stale (push) Has been cancelled
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CI / CI OK (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Issue Close Require / close-issues (push) Has been cancelled
This commit is contained in:
@@ -47,6 +47,7 @@
|
||||
"markdown-it": "^14.1.0",
|
||||
"pinia": "catalog:",
|
||||
"vue": "catalog:",
|
||||
"vue-router": "catalog:"
|
||||
"vue-router": "catalog:",
|
||||
"xlsx": "^0.18.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import type { RequestResponse } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
const prefix = 'china-medicine/';
|
||||
@@ -66,3 +64,35 @@ export async function deleteChinaMedicine(data: Record<string, any>) {
|
||||
export async function importChinaMedicineApi(data: Record<string, any>) {
|
||||
return requestClient.upload(`${prefix}import`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 预览批量更新药品编码(只读)
|
||||
*/
|
||||
export async function previewBatchDrugNumberApi(data: {
|
||||
items: { drug_name: string; drug_number: string }[];
|
||||
}) {
|
||||
return requestClient.post<any>(`${prefix}preview-batch-drug-number`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新编码:全量中药 id/名称/编号(卡片参考)
|
||||
*/
|
||||
export async function getAllDrugNumbersForBatchApi() {
|
||||
return requestClient.get<{
|
||||
items: {
|
||||
id: number;
|
||||
drug_name: string;
|
||||
drug_number: null | string;
|
||||
pinyin_simple: string;
|
||||
}[];
|
||||
}>(`${prefix}list-all-drug-numbers-for-batch`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认批量更新药品编码
|
||||
*/
|
||||
export async function applyBatchDrugNumberApi(data: {
|
||||
items: { id: number; drug_number: string }[];
|
||||
}) {
|
||||
return requestClient.post<any>(`${prefix}apply-batch-drug-number`, data);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,485 @@
|
||||
<script lang="ts" setup>
|
||||
import type { UploadFile } from 'ant-design-vue';
|
||||
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Input,
|
||||
message,
|
||||
Modal,
|
||||
Segmented,
|
||||
Spin,
|
||||
Table,
|
||||
Tag,
|
||||
UploadDragger,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
import {
|
||||
applyBatchDrugNumberApi,
|
||||
getAllDrugNumbersForBatchApi,
|
||||
previewBatchDrugNumberApi,
|
||||
} from '../api';
|
||||
import {
|
||||
isDrugNumberChanged,
|
||||
parseDrugNumberExcelBuffer,
|
||||
} from '../utils/parseDrugNumberExcel';
|
||||
|
||||
type MatchedRow = {
|
||||
id: number;
|
||||
drug_name: string;
|
||||
drug_number_old: string | null;
|
||||
drug_number_new: string;
|
||||
};
|
||||
|
||||
type MatchedRowView = MatchedRow & { _changed: boolean };
|
||||
|
||||
type AllDrugItem = {
|
||||
id: number;
|
||||
drug_name: string;
|
||||
drug_number: null | string;
|
||||
pinyin_simple?: string | null;
|
||||
};
|
||||
type CardStatusFilter = 'all' | 'changed' | 'unchanged';
|
||||
|
||||
const gridApi = ref();
|
||||
const fileList = ref<UploadFile[]>([]);
|
||||
const selectedFile = ref<File | null>(null);
|
||||
const matched = ref<MatchedRow[]>([]);
|
||||
const notFound = ref<{ drug_name: string; drug_number: string }[]>([]);
|
||||
const invalidRows = ref<{ row: number; drug_name: string; drug_number: string }[]>(
|
||||
[],
|
||||
);
|
||||
const previewLoading = ref(false);
|
||||
const applyLoading = ref(false);
|
||||
const parseHint = ref('');
|
||||
|
||||
const allDrugs = ref<AllDrugItem[]>([]);
|
||||
/** 打开弹窗时服务端原始编号,用于判断是否有变更 */
|
||||
const initialNumbers = ref<Record<number, string>>({});
|
||||
/** 当前编辑中的编号(卡片可改;导入解析会写入) */
|
||||
const localNumbers = ref<Record<number, string>>({});
|
||||
const loadingAll = ref(false);
|
||||
const cardFilter = ref('');
|
||||
const cardStatusFilter = ref<CardStatusFilter>('all');
|
||||
|
||||
const matchedView = computed<MatchedRowView[]>(() =>
|
||||
matched.value.map((row) => {
|
||||
const newNum =
|
||||
localNumbers.value[row.id] ?? String(row.drug_number_new ?? '');
|
||||
return {
|
||||
...row,
|
||||
drug_number_new: newNum,
|
||||
_changed: isDrugNumberChanged(initialNumbers.value[row.id], newNum),
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
const changedCount = computed(
|
||||
() => matchedView.value.filter((r) => r._changed).length,
|
||||
);
|
||||
const cardStatusCounts = computed(() => {
|
||||
const all = allDrugs.value.length;
|
||||
const changed = allDrugs.value.filter((d) => cardIsChanged(d)).length;
|
||||
return {
|
||||
all,
|
||||
changed,
|
||||
unchanged: all - changed,
|
||||
};
|
||||
});
|
||||
|
||||
/** 含卡片直接编辑:任意与初始值不同的条数 */
|
||||
const totalPendingChanges = computed(() =>
|
||||
allDrugs.value.filter((d) =>
|
||||
isDrugNumberChanged(
|
||||
initialNumbers.value[d.id],
|
||||
localNumbers.value[d.id],
|
||||
),
|
||||
).length,
|
||||
);
|
||||
|
||||
function cardIsChanged(d: AllDrugItem) {
|
||||
return isDrugNumberChanged(
|
||||
initialNumbers.value[d.id],
|
||||
localNumbers.value[d.id],
|
||||
);
|
||||
}
|
||||
|
||||
function setLocalNumber(id: number, v: string) {
|
||||
localNumbers.value = { ...localNumbers.value, [id]: v ?? '' };
|
||||
}
|
||||
|
||||
const filteredCards = computed(() => {
|
||||
const q = cardFilter.value.trim().toLowerCase();
|
||||
const keywordFiltered = allDrugs.value.filter((d) => {
|
||||
const nameOk = d.drug_name.toLowerCase().includes(q);
|
||||
const py = (d.pinyin_simple ?? '').toLowerCase();
|
||||
const pyOk = py.includes(q);
|
||||
return q ? nameOk || pyOk : true;
|
||||
});
|
||||
if (cardStatusFilter.value === 'changed') {
|
||||
return keywordFiltered.filter((d) => cardIsChanged(d));
|
||||
}
|
||||
if (cardStatusFilter.value === 'unchanged') {
|
||||
return keywordFiltered.filter((d) => !cardIsChanged(d));
|
||||
}
|
||||
return keywordFiltered;
|
||||
});
|
||||
|
||||
const columns = [
|
||||
{ title: 'ID', dataIndex: 'id', key: 'id', width: 72 },
|
||||
{ title: '药品名称', dataIndex: 'drug_name', key: 'drug_name', ellipsis: true },
|
||||
{
|
||||
title: '当前编号',
|
||||
dataIndex: 'drug_number_old',
|
||||
key: 'drug_number_old',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '新编号',
|
||||
dataIndex: 'drug_number_new',
|
||||
key: 'drug_number_new',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: '_changed',
|
||||
key: 'status',
|
||||
width: 88,
|
||||
},
|
||||
];
|
||||
|
||||
function resetState() {
|
||||
selectedFile.value = null;
|
||||
fileList.value = [];
|
||||
matched.value = [];
|
||||
notFound.value = [];
|
||||
invalidRows.value = [];
|
||||
parseHint.value = '';
|
||||
cardFilter.value = '';
|
||||
cardStatusFilter.value = 'all';
|
||||
allDrugs.value = [];
|
||||
initialNumbers.value = {};
|
||||
localNumbers.value = {};
|
||||
}
|
||||
|
||||
const [ModalComp, modalApi] = useVbenModal({
|
||||
fullscreenButton: false,
|
||||
draggable: true,
|
||||
showConfirmButton: false,
|
||||
class: '!w-[min(960px,92vw)]',
|
||||
onCancel() {
|
||||
resetState();
|
||||
modalApi.close();
|
||||
},
|
||||
onOpenChange(isOpen: boolean) {
|
||||
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
|
||||
if (isOpen) {
|
||||
loadAllDrugs();
|
||||
} else {
|
||||
resetState();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
async function loadAllDrugs() {
|
||||
loadingAll.value = true;
|
||||
try {
|
||||
const res = await getAllDrugNumbersForBatchApi();
|
||||
const items = res?.items ?? [];
|
||||
allDrugs.value = items;
|
||||
const init: Record<number, string> = {};
|
||||
const loc: Record<number, string> = {};
|
||||
for (const d of items) {
|
||||
const s = d.drug_number ?? '';
|
||||
init[d.id] = s;
|
||||
loc[d.id] = s;
|
||||
}
|
||||
initialNumbers.value = init;
|
||||
localNumbers.value = loc;
|
||||
} catch {
|
||||
message.error('加载中药列表失败');
|
||||
allDrugs.value = [];
|
||||
initialNumbers.value = {};
|
||||
localNumbers.value = {};
|
||||
} finally {
|
||||
loadingAll.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
const handleFileChange = (info: { file: UploadFile }) => {
|
||||
const { file } = info;
|
||||
if (file.status === 'removed') {
|
||||
selectedFile.value = null;
|
||||
matched.value = [];
|
||||
notFound.value = [];
|
||||
invalidRows.value = [];
|
||||
parseHint.value = '';
|
||||
return;
|
||||
}
|
||||
const raw = file.originFileObj ?? file;
|
||||
if (raw instanceof File) {
|
||||
selectedFile.value = raw;
|
||||
}
|
||||
};
|
||||
|
||||
function rowClassName(record: MatchedRowView) {
|
||||
return record._changed ? 'drug-batch-row-changed' : 'drug-batch-row-unchanged';
|
||||
}
|
||||
|
||||
async function runPreview() {
|
||||
if (!selectedFile.value) {
|
||||
message.warning('请先选择 Excel 文件');
|
||||
return;
|
||||
}
|
||||
previewLoading.value = true;
|
||||
try {
|
||||
const buf = await selectedFile.value.arrayBuffer();
|
||||
const { items, invalidCount, rowCount } = parseDrugNumberExcelBuffer(buf);
|
||||
if (items.length === 0) {
|
||||
message.warning('未解析到有效的「药品编号」与「药品名称」行');
|
||||
matched.value = [];
|
||||
notFound.value = [];
|
||||
invalidRows.value = [];
|
||||
parseHint.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
parseHint.value =
|
||||
rowCount > 5000
|
||||
? `共 ${rowCount} 行,已按上限处理前 5000 行。`
|
||||
: `共解析 ${items.length} 条有效行。`;
|
||||
|
||||
const res = await previewBatchDrugNumberApi({ items });
|
||||
matched.value = (res.matched || []) as MatchedRow[];
|
||||
notFound.value = res.not_found || [];
|
||||
invalidRows.value = res.invalid || [];
|
||||
for (const m of matched.value) {
|
||||
const v = String(m.drug_number_new ?? '');
|
||||
localNumbers.value = { ...localNumbers.value, [m.id]: v };
|
||||
}
|
||||
if (invalidCount > 0) {
|
||||
message.info(`Excel 中有 ${invalidCount} 行因缺少编号或名称被跳过`);
|
||||
}
|
||||
if ((notFound.value?.length || 0) > 0) {
|
||||
Modal.warning({
|
||||
title: '部分药品名称在系统中未找到',
|
||||
content: `未匹配 ${notFound.value.length} 条,请核对药名是否与后台完全一致。`,
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
message.error('预览失败');
|
||||
} finally {
|
||||
previewLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function runApply() {
|
||||
const items = allDrugs.value
|
||||
.filter((d) =>
|
||||
isDrugNumberChanged(
|
||||
initialNumbers.value[d.id],
|
||||
localNumbers.value[d.id],
|
||||
),
|
||||
)
|
||||
.map((d) => ({
|
||||
id: d.id,
|
||||
drug_number: String(localNumbers.value[d.id] ?? ''),
|
||||
}));
|
||||
if (items.length === 0) {
|
||||
message.info('没有需要更新的编号(与打开弹窗时一致)');
|
||||
return;
|
||||
}
|
||||
|
||||
applyLoading.value = true;
|
||||
modalApi.setState({ loading: true });
|
||||
try {
|
||||
const res = await applyBatchDrugNumberApi({ items });
|
||||
const n = res?.updated_count ?? res?.updatedCount ?? 0;
|
||||
message.success(`已更新 ${n} 条记录`);
|
||||
gridApi.value?.reload();
|
||||
resetState();
|
||||
modalApi.close();
|
||||
} catch {
|
||||
message.error('更新失败');
|
||||
} finally {
|
||||
applyLoading.value = false;
|
||||
modalApi.setState({ loading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ModalComp title="批量更新药品编码">
|
||||
<div class="mb-3 text-sm text-gray-600 dark:text-gray-300">
|
||||
下方卡片可直接修改编号;亦可使用 Excel:首列表头为「药品编号/药品编码」、第二列「药品名称」,或与之一致的列顺序。仅更新编号与更新时间。
|
||||
</div>
|
||||
|
||||
<Spin :spinning="loadingAll">
|
||||
<div class="mb-1 text-sm font-medium text-gray-800 dark:text-gray-100">
|
||||
当前中药参考
|
||||
<Tag>{{ filteredCards.length }}</Tag>
|
||||
条
|
||||
</div>
|
||||
<Input
|
||||
v-model:value="cardFilter"
|
||||
allow-clear
|
||||
class="mb-2"
|
||||
placeholder="按药品名称或拼音首拼筛选"
|
||||
/>
|
||||
<Segmented
|
||||
v-model:value="cardStatusFilter"
|
||||
class="mb-2"
|
||||
:options="[
|
||||
{ label: `全部 ${cardStatusCounts.all}`, value: 'all' },
|
||||
{ label: `有变动 ${cardStatusCounts.changed}`, value: 'changed' },
|
||||
{
|
||||
label: `无变动 ${cardStatusCounts.unchanged}`,
|
||||
value: 'unchanged',
|
||||
},
|
||||
]"
|
||||
/>
|
||||
<div
|
||||
class="mb-4 grid max-h-56 grid-cols-2 gap-2 overflow-y-auto sm:grid-cols-3 md:grid-cols-4"
|
||||
>
|
||||
<Card
|
||||
v-for="d in filteredCards"
|
||||
:key="d.id"
|
||||
:class="[
|
||||
'!mb-0 shadow-sm transition-colors',
|
||||
cardIsChanged(d)
|
||||
? '!border-amber-400 bg-amber-50 dark:!border-amber-500/70 dark:bg-amber-950/45'
|
||||
: '',
|
||||
]"
|
||||
size="small"
|
||||
>
|
||||
<div
|
||||
class="truncate text-sm font-medium text-gray-900 dark:text-gray-100"
|
||||
:title="d.drug_name"
|
||||
>
|
||||
{{ d.drug_name }}
|
||||
</div>
|
||||
<Input
|
||||
class="mt-1"
|
||||
placeholder="药品编号"
|
||||
size="small"
|
||||
:value="localNumbers[d.id] ?? ''"
|
||||
@update:value="(v: string) => setLocalNumber(d.id, v)"
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
</Spin>
|
||||
|
||||
<UploadDragger
|
||||
v-model:file-list="fileList"
|
||||
:before-upload="() => false"
|
||||
:max-count="1"
|
||||
accept=".xlsx,.xls"
|
||||
name="file"
|
||||
@change="handleFileChange"
|
||||
>
|
||||
<p class="ant-upload-text">点击或拖拽选择 Excel</p>
|
||||
<p class="ant-upload-hint">选择后点击「导入并解析」从服务器比对当前编号</p>
|
||||
</UploadDragger>
|
||||
|
||||
<div class="mt-3 flex flex-wrap gap-2">
|
||||
<Button
|
||||
:loading="previewLoading"
|
||||
type="primary"
|
||||
@click="runPreview"
|
||||
>
|
||||
导入并解析
|
||||
</Button>
|
||||
<Button
|
||||
:disabled="totalPendingChanges === 0"
|
||||
:loading="applyLoading"
|
||||
danger
|
||||
type="primary"
|
||||
@click="runApply"
|
||||
>
|
||||
确认更新到数据库
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<p v-if="parseHint" class="mt-2 text-xs text-gray-500 dark:text-gray-400">
|
||||
{{ parseHint }}
|
||||
</p>
|
||||
|
||||
<div class="mt-2 text-sm text-gray-600 dark:text-gray-300">
|
||||
待保存变更:
|
||||
<Tag :color="totalPendingChanges > 0 ? 'orange' : 'default'">{{
|
||||
totalPendingChanges
|
||||
}}</Tag>
|
||||
条(含卡片修改与导入)
|
||||
</div>
|
||||
|
||||
<div v-if="matched.length > 0" class="mt-4">
|
||||
<div class="mb-2 text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||
本次 Excel 匹配
|
||||
<Tag color="blue">{{ matched.length }}</Tag>
|
||||
条,其中
|
||||
<Tag v-if="changedCount > 0" color="orange">{{ changedCount }}</Tag>
|
||||
<Tag v-else color="default">0</Tag>
|
||||
条与初始编号不同
|
||||
</div>
|
||||
<Table
|
||||
:columns="columns"
|
||||
:data-source="matchedView"
|
||||
:pagination="{ pageSize: 8 }"
|
||||
:row-class-name="(record: MatchedRowView) => rowClassName(record)"
|
||||
:row-key="(row: MatchedRowView, index: number) => `${row.id}-${index}`"
|
||||
:scroll="{ y: 280 }"
|
||||
size="small"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'status'">
|
||||
<Tag v-if="record._changed" color="orange">已变更</Tag>
|
||||
<Tag v-else color="default">无变化</Tag>
|
||||
</template>
|
||||
</template>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<div v-if="notFound.length > 0" class="mt-4">
|
||||
<div class="mb-1 text-sm font-medium text-orange-600 dark:text-orange-400">
|
||||
未找到对应中药({{ notFound.length }})
|
||||
</div>
|
||||
<div
|
||||
class="max-h-32 overflow-auto rounded border border-orange-100 bg-orange-50 p-2 text-xs text-gray-800 dark:border-orange-900/60 dark:bg-orange-950/40 dark:text-gray-200"
|
||||
>
|
||||
<div v-for="(row, i) in notFound.slice(0, 50)" :key="i">
|
||||
{{ row.drug_name }} — {{ row.drug_number }}
|
||||
</div>
|
||||
<div v-if="notFound.length > 50">… 其余 {{ notFound.length - 50 }} 条略</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="invalidRows.length > 0"
|
||||
class="mt-2 text-xs text-gray-500 dark:text-gray-400"
|
||||
>
|
||||
服务端标记无效行:{{ invalidRows.length }} 条
|
||||
</div>
|
||||
</ModalComp>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.drug-batch-row-changed) > td {
|
||||
background-color: rgb(254 252 232) !important;
|
||||
}
|
||||
|
||||
:deep(.dark .drug-batch-row-changed) > td {
|
||||
background-color: rgb(69 26 3 / 0.45) !important;
|
||||
}
|
||||
|
||||
:deep(.drug-batch-row-unchanged) > td {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
:deep(.dark .drug-batch-row-unchanged) > td {
|
||||
opacity: 0.92;
|
||||
}
|
||||
</style>
|
||||
@@ -25,6 +25,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
{ type: 'checkbox', width: 60 },
|
||||
{ field: 'id', align: 'left', title: 'ID', width: 100 },
|
||||
{ field: 'drug_name', align: 'left', title: '药品名称' },
|
||||
{ field: 'drug_number', align: 'left', title: '药品编码(erp)' },
|
||||
{ field: 'pinyin_simple', title: '拼音' },
|
||||
{ field: 'status', title: '状态', slots: { default: 'status' } },
|
||||
{ field: 'created_at', title: '发布时间' },
|
||||
|
||||
@@ -12,6 +12,7 @@ import { TableAction } from '#/components/table-action';
|
||||
import { downloadByData } from '#/util/tool';
|
||||
|
||||
import { deleteChinaMedicine, exportChinaMedicineApi } from './api';
|
||||
import DrugNumberBatchModal from './components/DrugNumberBatchModal.vue';
|
||||
import FormModalDemo from './components/modal.vue';
|
||||
import ExcelUpload from './components/ExcelUpload.vue';
|
||||
import { formOptions } from './config/search';
|
||||
@@ -46,6 +47,10 @@ const [ExcelUploadModal, ExcelUploadModalApi] = useVbenModal({
|
||||
connectedComponent: ExcelUpload,
|
||||
});
|
||||
|
||||
const [DrugNumberBatchModalComp, drugNumberBatchModalApi] = useVbenModal({
|
||||
connectedComponent: DrugNumberBatchModal,
|
||||
});
|
||||
|
||||
const showModal = (data = {}, isUpdate = false) => {
|
||||
formModalApi.setData({
|
||||
// 表单值
|
||||
@@ -86,11 +91,19 @@ const openExcelUploadModal = () => {
|
||||
});
|
||||
ExcelUploadModalApi.open();
|
||||
};
|
||||
|
||||
const openDrugNumberBatchModal = () => {
|
||||
drugNumberBatchModalApi.setData({
|
||||
gridApi,
|
||||
});
|
||||
drugNumberBatchModalApi.open();
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page auto-content-height title="中药管理">
|
||||
<ExcelUploadModal />
|
||||
<DrugNumberBatchModalComp />
|
||||
<FormModal />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
@@ -110,6 +123,12 @@ const openExcelUploadModal = () => {
|
||||
// auth: ['超级中药', 'sys:user:save'],
|
||||
onClick: openExcelUploadModal.bind(null),
|
||||
},
|
||||
{
|
||||
label: '批量更新编码',
|
||||
type: 'default',
|
||||
icon: 'ant-design:barcode-outlined',
|
||||
onClick: openDrugNumberBatchModal.bind(null),
|
||||
},
|
||||
{
|
||||
label: '导出',
|
||||
type: 'primary',
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
import * as XLSX from 'xlsx';
|
||||
|
||||
const MAX_ROWS = 5000;
|
||||
|
||||
export type ParsedDrugNumberRow = {
|
||||
drug_name: string;
|
||||
drug_number: string;
|
||||
};
|
||||
|
||||
function normalizeCell(value: unknown): string {
|
||||
if (value === null || value === undefined) {
|
||||
return '';
|
||||
}
|
||||
if (typeof value === 'number') {
|
||||
return Number.isInteger(value) ? String(value) : String(value).trim();
|
||||
}
|
||||
return String(value).trim();
|
||||
}
|
||||
|
||||
/** 表头含空白或全角空格时仍能匹配 */
|
||||
function pickByHeaderAliases(
|
||||
row: Record<string, unknown>,
|
||||
aliases: string[],
|
||||
): string {
|
||||
for (const key of Object.keys(row)) {
|
||||
const k = key.replace(/\s+/g, '').replace(/\u3000/g, '');
|
||||
for (const alias of aliases) {
|
||||
if (k === alias.replace(/\s+/g, '').replace(/\u3000/g, '')) {
|
||||
return normalizeCell(row[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function parseRowsByObjectKeys(
|
||||
rows: Record<string, unknown>[],
|
||||
): { items: ParsedDrugNumberRow[]; invalidCount: number } {
|
||||
const items: ParsedDrugNumberRow[] = [];
|
||||
let invalidCount = 0;
|
||||
const n = Math.min(rows.length, MAX_ROWS);
|
||||
|
||||
const numberAliases = [
|
||||
'药品编号',
|
||||
'药品编码',
|
||||
'编号',
|
||||
'drug_number',
|
||||
'编码',
|
||||
];
|
||||
const nameAliases = ['药品名称', '药名', 'drug_name', '名称'];
|
||||
|
||||
for (let i = 0; i < n; i++) {
|
||||
const row = rows[i];
|
||||
if (!row || typeof row !== 'object') {
|
||||
invalidCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
let drugNumber =
|
||||
pickByHeaderAliases(row, numberAliases) ||
|
||||
normalizeCell(row['药品编号']) ||
|
||||
normalizeCell(row['药品编码']) ||
|
||||
normalizeCell(row['编号']) ||
|
||||
normalizeCell(row['drug_number']);
|
||||
|
||||
let drugName =
|
||||
pickByHeaderAliases(row, nameAliases) ||
|
||||
normalizeCell(row['药品名称']) ||
|
||||
normalizeCell(row['药名']) ||
|
||||
normalizeCell(row['drug_name']);
|
||||
|
||||
if (!drugName || !drugNumber) {
|
||||
const empty = !Object.values(row).some(
|
||||
(v) => normalizeCell(v) !== '',
|
||||
);
|
||||
if (empty) {
|
||||
continue;
|
||||
}
|
||||
invalidCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
items.push({
|
||||
drug_name: drugName,
|
||||
drug_number: drugNumber,
|
||||
});
|
||||
}
|
||||
|
||||
return { items, invalidCount };
|
||||
}
|
||||
|
||||
/**
|
||||
* 标准「药品编码」表:第 1 列为编号、第 2 列为名称(表头行自动跳过)
|
||||
*/
|
||||
function parseRowsByPosition(sheet: XLSX.WorkSheet): {
|
||||
items: ParsedDrugNumberRow[];
|
||||
invalidCount: number;
|
||||
rowCount: number;
|
||||
} {
|
||||
const aoa = XLSX.utils.sheet_to_json(sheet, {
|
||||
header: 1,
|
||||
defval: '',
|
||||
}) as unknown[][];
|
||||
|
||||
const items: ParsedDrugNumberRow[] = [];
|
||||
let invalidCount = 0;
|
||||
if (aoa.length === 0) {
|
||||
return { items: [], invalidCount: 0, rowCount: 0 };
|
||||
}
|
||||
|
||||
let start = 0;
|
||||
const h0 = normalizeCell(aoa[0]?.[0]);
|
||||
const h1 = normalizeCell(aoa[0]?.[1]);
|
||||
if (
|
||||
h0 &&
|
||||
(h0.includes('编号') ||
|
||||
h0.includes('编码') ||
|
||||
h0.includes('代码') ||
|
||||
/药品/.test(h0))
|
||||
) {
|
||||
start = 1;
|
||||
}
|
||||
if (
|
||||
h1 &&
|
||||
(h1.includes('名称') || h1.includes('药名') || h1.includes('品名'))
|
||||
) {
|
||||
start = 1;
|
||||
}
|
||||
|
||||
const limit = Math.min(aoa.length, start + MAX_ROWS);
|
||||
for (let i = start; i < limit; i++) {
|
||||
const row = aoa[i];
|
||||
if (!row?.length) {
|
||||
continue;
|
||||
}
|
||||
const drugNumber = normalizeCell(row[0]);
|
||||
const drugName = normalizeCell(row[1]);
|
||||
if (!drugName || !drugNumber) {
|
||||
const anyCell = row.some((c) => normalizeCell(c) !== '');
|
||||
if (anyCell) {
|
||||
invalidCount++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
items.push({ drug_name: drugName, drug_number: drugNumber });
|
||||
}
|
||||
|
||||
return { items, invalidCount, rowCount: aoa.length };
|
||||
}
|
||||
|
||||
/**
|
||||
* 从第一张工作表解析「药品编号」「药品名称」列(兼容表头别名 + 列位置回退)
|
||||
*/
|
||||
export function parseDrugNumberExcelBuffer(buffer: ArrayBuffer): {
|
||||
items: ParsedDrugNumberRow[];
|
||||
invalidCount: number;
|
||||
rowCount: number;
|
||||
} {
|
||||
const workbook = XLSX.read(buffer, { type: 'array' });
|
||||
const sheetName = workbook.SheetNames[0];
|
||||
if (!sheetName) {
|
||||
return { items: [], invalidCount: 0, rowCount: 0 };
|
||||
}
|
||||
const sheet = workbook.Sheets[sheetName];
|
||||
if (!sheet) {
|
||||
return { items: [], invalidCount: 0, rowCount: 0 };
|
||||
}
|
||||
|
||||
const rows = XLSX.utils.sheet_to_json<Record<string, unknown>>(sheet, {
|
||||
defval: '',
|
||||
});
|
||||
|
||||
let { items, invalidCount } = parseRowsByObjectKeys(rows);
|
||||
let rowCount = rows.length;
|
||||
|
||||
if (items.length === 0) {
|
||||
const pos = parseRowsByPosition(sheet);
|
||||
items = pos.items;
|
||||
invalidCount = pos.invalidCount;
|
||||
rowCount = pos.rowCount;
|
||||
}
|
||||
|
||||
return {
|
||||
items,
|
||||
invalidCount,
|
||||
rowCount,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 与后端 `normalizeDrugNumberForBatch` 对齐,用于对比是否变更
|
||||
*/
|
||||
export function normalizeDrugNumberForCompare(value: unknown): string {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '';
|
||||
}
|
||||
if (typeof value === 'boolean') {
|
||||
return '';
|
||||
}
|
||||
if (typeof value === 'number') {
|
||||
if (Number.isInteger(value) || Math.floor(value) === value) {
|
||||
return String(Math.trunc(value));
|
||||
}
|
||||
return String(value).trim();
|
||||
}
|
||||
return String(value).trim();
|
||||
}
|
||||
|
||||
export function isDrugNumberChanged(
|
||||
oldVal: unknown,
|
||||
newVal: unknown,
|
||||
): boolean {
|
||||
return normalizeDrugNumberForCompare(oldVal) !== normalizeDrugNumberForCompare(newVal);
|
||||
}
|
||||
@@ -221,10 +221,10 @@ function getDrugUseListByWesternModal() {
|
||||
|
||||
getDrugUseListByWesternModal();
|
||||
|
||||
const selectProductId = ref(0);
|
||||
const selectProductIndex = ref(-1);
|
||||
|
||||
function selectProductChange(id) {
|
||||
selectProductId.value = id;
|
||||
selectProductIndex.value = id;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,16 +232,18 @@ function selectProductChange(id) {
|
||||
* @param id
|
||||
*/
|
||||
function selectDrugUseWayChange(id) {
|
||||
currentDrugs.value = currentDrugs.value.map((item) =>
|
||||
// 修改item下面drug的 frequency_id = id
|
||||
item.index_id === selectProductId.value
|
||||
? {
|
||||
...item,
|
||||
way_id: id,
|
||||
use_ways: drugUseWay.value.find((value) => value.id === id),
|
||||
}
|
||||
: item,
|
||||
);
|
||||
if (
|
||||
selectProductIndex.value < 0 ||
|
||||
selectProductIndex.value >= currentDrugs.value.length
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const targetDrug = currentDrugs.value[selectProductIndex.value];
|
||||
if (!targetDrug) {
|
||||
return;
|
||||
}
|
||||
targetDrug.way_id = id;
|
||||
targetDrug.use_ways = drugUseWay.value.find((value) => value.id === id);
|
||||
updateLocalStorage();
|
||||
}
|
||||
|
||||
@@ -1945,7 +1947,7 @@ watch(
|
||||
<Row>
|
||||
<Col
|
||||
v-for="(drug, index) in currentDrugs"
|
||||
:key="drug.id"
|
||||
:key="`${drug.index_id || drug.id}-${index}`"
|
||||
:lg="12"
|
||||
:md="24"
|
||||
:sm="24"
|
||||
@@ -2000,7 +2002,7 @@ watch(
|
||||
placeholder="用法"
|
||||
@change="selectDrugUseWayChange"
|
||||
@dropdown-visible-change="
|
||||
selectProductChange(drug.index_id)
|
||||
selectProductChange(index)
|
||||
"
|
||||
>
|
||||
<SelectOption :value="0">煎服</SelectOption>
|
||||
|
||||
569
pnpm-lock.yaml
generated
569
pnpm-lock.yaml
generated
@@ -12,51 +12,387 @@ catalogs:
|
||||
'@changesets/cli':
|
||||
specifier: ^2.27.11
|
||||
version: 2.27.11
|
||||
'@changesets/git':
|
||||
specifier: ^3.0.2
|
||||
version: 3.0.2
|
||||
'@clack/prompts':
|
||||
specifier: ^0.9.0
|
||||
version: 0.9.0
|
||||
'@commitlint/cli':
|
||||
specifier: ^19.6.1
|
||||
version: 19.6.1
|
||||
'@commitlint/config-conventional':
|
||||
specifier: ^19.6.0
|
||||
version: 19.6.0
|
||||
'@eslint/js':
|
||||
specifier: ^9.17.0
|
||||
version: 9.17.0
|
||||
'@iconify/json':
|
||||
specifier: ^2.2.286
|
||||
version: 2.2.286
|
||||
'@iconify/tailwind':
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0
|
||||
'@iconify/vue':
|
||||
specifier: ^4.2.0
|
||||
version: 4.2.0
|
||||
'@intlify/core-base':
|
||||
specifier: ^10.0.5
|
||||
version: 10.0.5
|
||||
'@intlify/unplugin-vue-i18n':
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.1
|
||||
'@jspm/generator':
|
||||
specifier: ^2.4.1
|
||||
version: 2.4.1
|
||||
'@manypkg/get-packages':
|
||||
specifier: ^2.2.2
|
||||
version: 2.2.2
|
||||
'@playwright/test':
|
||||
specifier: ^1.49.1
|
||||
version: 1.49.1
|
||||
'@pnpm/workspace.read-manifest':
|
||||
specifier: ^1000.0.1
|
||||
version: 1000.0.1
|
||||
'@stylistic/stylelint-plugin':
|
||||
specifier: ^3.1.1
|
||||
version: 3.1.1
|
||||
'@tailwindcss/nesting':
|
||||
specifier: 0.0.0-insiders.565cd3e
|
||||
version: 0.0.0-insiders.565cd3e
|
||||
'@tailwindcss/typography':
|
||||
specifier: ^0.5.15
|
||||
version: 0.5.15
|
||||
'@tanstack/vue-query':
|
||||
specifier: ^5.62.8
|
||||
version: 5.62.8
|
||||
'@tanstack/vue-store':
|
||||
specifier: ^0.6.0
|
||||
version: 0.6.0
|
||||
'@types/archiver':
|
||||
specifier: ^6.0.3
|
||||
version: 6.0.3
|
||||
'@types/eslint':
|
||||
specifier: ^9.6.1
|
||||
version: 9.6.1
|
||||
'@types/html-minifier-terser':
|
||||
specifier: ^7.0.2
|
||||
version: 7.0.2
|
||||
'@types/lodash.clonedeep':
|
||||
specifier: ^4.5.9
|
||||
version: 4.5.9
|
||||
'@types/lodash.get':
|
||||
specifier: ^4.4.9
|
||||
version: 4.4.9
|
||||
'@types/lodash.isequal':
|
||||
specifier: ^4.5.8
|
||||
version: 4.5.8
|
||||
'@types/node':
|
||||
specifier: ^22.10.2
|
||||
version: 22.10.2
|
||||
'@types/nprogress':
|
||||
specifier: ^0.2.3
|
||||
version: 0.2.3
|
||||
'@types/postcss-import':
|
||||
specifier: ^14.0.3
|
||||
version: 14.0.3
|
||||
'@types/qrcode':
|
||||
specifier: ^1.5.5
|
||||
version: 1.5.5
|
||||
'@types/sortablejs':
|
||||
specifier: ^1.15.8
|
||||
version: 1.15.8
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
specifier: ^8.18.1
|
||||
version: 8.18.1
|
||||
'@typescript-eslint/parser':
|
||||
specifier: ^8.18.1
|
||||
version: 8.18.1
|
||||
'@vee-validate/zod':
|
||||
specifier: ^4.14.7
|
||||
version: 4.14.7
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^5.2.1
|
||||
version: 5.2.1
|
||||
'@vitejs/plugin-vue-jsx':
|
||||
specifier: ^4.1.1
|
||||
version: 4.1.1
|
||||
'@vue/shared':
|
||||
specifier: ^3.5.13
|
||||
version: 3.5.13
|
||||
'@vue/test-utils':
|
||||
specifier: ^2.4.6
|
||||
version: 2.4.6
|
||||
'@vueuse/core':
|
||||
specifier: ^12.0.0
|
||||
version: 12.0.0
|
||||
'@vueuse/integrations':
|
||||
specifier: ^12.0.0
|
||||
version: 12.0.0
|
||||
ant-design-vue:
|
||||
specifier: ^4.2.6
|
||||
version: 4.2.6
|
||||
archiver:
|
||||
specifier: ^7.0.1
|
||||
version: 7.0.1
|
||||
autoprefixer:
|
||||
specifier: ^10.4.20
|
||||
version: 10.4.20
|
||||
axios:
|
||||
specifier: ^1.7.9
|
||||
version: 1.7.9
|
||||
axios-mock-adapter:
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
cac:
|
||||
specifier: ^6.7.14
|
||||
version: 6.7.14
|
||||
chalk:
|
||||
specifier: ^5.4.0
|
||||
version: 5.4.0
|
||||
cheerio:
|
||||
specifier: 1.0.0
|
||||
version: 1.0.0
|
||||
circular-dependency-scanner:
|
||||
specifier: ^2.3.0
|
||||
version: 2.3.0
|
||||
class-variance-authority:
|
||||
specifier: ^0.7.1
|
||||
version: 0.7.1
|
||||
commitlint-plugin-function-rules:
|
||||
specifier: ^4.0.1
|
||||
version: 4.0.1
|
||||
consola:
|
||||
specifier: ^3.3.0
|
||||
version: 3.3.0
|
||||
cross-env:
|
||||
specifier: ^7.0.3
|
||||
version: 7.0.3
|
||||
cspell:
|
||||
specifier: ^8.17.1
|
||||
version: 8.17.1
|
||||
cssnano:
|
||||
specifier: ^7.0.6
|
||||
version: 7.0.6
|
||||
cz-git:
|
||||
specifier: ^1.11.0
|
||||
version: 1.11.0
|
||||
czg:
|
||||
specifier: ^1.11.0
|
||||
version: 1.11.0
|
||||
dayjs:
|
||||
specifier: ^1.11.13
|
||||
version: 1.11.13
|
||||
defu:
|
||||
specifier: ^6.1.4
|
||||
version: 6.1.4
|
||||
depcheck:
|
||||
specifier: ^1.4.7
|
||||
version: 1.4.7
|
||||
dotenv:
|
||||
specifier: ^16.4.7
|
||||
version: 16.4.7
|
||||
echarts:
|
||||
specifier: ^5.5.1
|
||||
version: 5.5.1
|
||||
eslint:
|
||||
specifier: ^9.17.0
|
||||
version: 9.17.0
|
||||
eslint-config-turbo:
|
||||
specifier: ^2.3.3
|
||||
version: 2.3.3
|
||||
eslint-plugin-command:
|
||||
specifier: ^0.2.7
|
||||
version: 0.2.7
|
||||
eslint-plugin-eslint-comments:
|
||||
specifier: ^3.2.0
|
||||
version: 3.2.0
|
||||
eslint-plugin-import-x:
|
||||
specifier: ^4.6.1
|
||||
version: 4.6.1
|
||||
eslint-plugin-jsdoc:
|
||||
specifier: ^50.6.1
|
||||
version: 50.6.1
|
||||
eslint-plugin-jsonc:
|
||||
specifier: ^2.18.2
|
||||
version: 2.18.2
|
||||
eslint-plugin-n:
|
||||
specifier: ^17.15.1
|
||||
version: 17.15.1
|
||||
eslint-plugin-no-only-tests:
|
||||
specifier: ^3.3.0
|
||||
version: 3.3.0
|
||||
eslint-plugin-perfectionist:
|
||||
specifier: ^3.9.1
|
||||
version: 3.9.1
|
||||
eslint-plugin-prettier:
|
||||
specifier: ^5.2.1
|
||||
version: 5.2.1
|
||||
eslint-plugin-regexp:
|
||||
specifier: ^2.7.0
|
||||
version: 2.7.0
|
||||
eslint-plugin-unicorn:
|
||||
specifier: ^56.0.1
|
||||
version: 56.0.1
|
||||
eslint-plugin-unused-imports:
|
||||
specifier: ^4.1.4
|
||||
version: 4.1.4
|
||||
eslint-plugin-vitest:
|
||||
specifier: ^0.5.4
|
||||
version: 0.5.4
|
||||
eslint-plugin-vue:
|
||||
specifier: ^9.32.0
|
||||
version: 9.32.0
|
||||
execa:
|
||||
specifier: ^9.5.2
|
||||
version: 9.5.2
|
||||
find-up:
|
||||
specifier: ^7.0.0
|
||||
version: 7.0.0
|
||||
get-port:
|
||||
specifier: ^7.1.0
|
||||
version: 7.1.0
|
||||
globals:
|
||||
specifier: ^15.14.0
|
||||
version: 15.14.0
|
||||
happy-dom:
|
||||
specifier: ^15.11.7
|
||||
version: 15.11.7
|
||||
html-minifier-terser:
|
||||
specifier: ^7.2.0
|
||||
version: 7.2.0
|
||||
husky:
|
||||
specifier: ^9.1.7
|
||||
version: 9.1.7
|
||||
is-ci:
|
||||
specifier: ^4.1.0
|
||||
version: 4.1.0
|
||||
jsonc-eslint-parser:
|
||||
specifier: ^2.4.0
|
||||
version: 2.4.0
|
||||
lint-staged:
|
||||
specifier: ^15.2.11
|
||||
version: 15.2.11
|
||||
lodash.clonedeep:
|
||||
specifier: ^4.5.0
|
||||
version: 4.5.0
|
||||
lodash.get:
|
||||
specifier: ^4.4.2
|
||||
version: 4.4.2
|
||||
lodash.isequal:
|
||||
specifier: ^4.5.0
|
||||
version: 4.5.0
|
||||
lucide-vue-next:
|
||||
specifier: ^0.469.0
|
||||
version: 0.469.0
|
||||
nitropack:
|
||||
specifier: ^2.10.4
|
||||
version: 2.10.4
|
||||
nprogress:
|
||||
specifier: ^0.2.0
|
||||
version: 0.2.0
|
||||
ora:
|
||||
specifier: ^8.1.1
|
||||
version: 8.1.1
|
||||
pinia-plugin-persistedstate:
|
||||
specifier: ^4.2.0
|
||||
version: 4.2.0
|
||||
pkg-types:
|
||||
specifier: ^1.2.1
|
||||
version: 1.2.1
|
||||
playwright:
|
||||
specifier: ^1.49.1
|
||||
version: 1.49.1
|
||||
postcss:
|
||||
specifier: ^8.4.49
|
||||
version: 8.4.49
|
||||
postcss-antd-fixes:
|
||||
specifier: ^0.2.0
|
||||
version: 0.2.0
|
||||
postcss-html:
|
||||
specifier: ^1.7.0
|
||||
version: 1.7.0
|
||||
postcss-import:
|
||||
specifier: ^16.1.0
|
||||
version: 16.1.0
|
||||
postcss-preset-env:
|
||||
specifier: ^10.1.2
|
||||
version: 10.1.2
|
||||
postcss-scss:
|
||||
specifier: ^4.0.9
|
||||
version: 4.0.9
|
||||
prettier:
|
||||
specifier: ^3.4.2
|
||||
version: 3.4.2
|
||||
prettier-plugin-tailwindcss:
|
||||
specifier: ^0.6.9
|
||||
version: 0.6.9
|
||||
publint:
|
||||
specifier: ^0.2.12
|
||||
version: 0.2.12
|
||||
qrcode:
|
||||
specifier: ^1.5.4
|
||||
version: 1.5.4
|
||||
radix-vue:
|
||||
specifier: ^1.9.11
|
||||
version: 1.9.11
|
||||
resolve.exports:
|
||||
specifier: ^2.0.3
|
||||
version: 2.0.3
|
||||
rimraf:
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.1
|
||||
rollup:
|
||||
specifier: ^4.28.1
|
||||
version: 4.28.1
|
||||
rollup-plugin-visualizer:
|
||||
specifier: ^5.12.0
|
||||
version: 5.12.0
|
||||
sass:
|
||||
specifier: 1.80.6
|
||||
version: 1.80.6
|
||||
sortablejs:
|
||||
specifier: ^1.15.6
|
||||
version: 1.15.6
|
||||
stylelint:
|
||||
specifier: ^16.12.0
|
||||
version: 16.12.0
|
||||
stylelint-config-recess-order:
|
||||
specifier: ^5.1.1
|
||||
version: 5.1.1
|
||||
stylelint-config-recommended:
|
||||
specifier: ^14.0.1
|
||||
version: 14.0.1
|
||||
stylelint-config-recommended-scss:
|
||||
specifier: ^14.1.0
|
||||
version: 14.1.0
|
||||
stylelint-config-recommended-vue:
|
||||
specifier: ^1.5.0
|
||||
version: 1.5.0
|
||||
stylelint-config-standard:
|
||||
specifier: ^36.0.1
|
||||
version: 36.0.1
|
||||
stylelint-order:
|
||||
specifier: ^6.0.4
|
||||
version: 6.0.4
|
||||
stylelint-prettier:
|
||||
specifier: ^5.0.2
|
||||
version: 5.0.2
|
||||
stylelint-scss:
|
||||
specifier: ^6.10.0
|
||||
version: 6.10.0
|
||||
tailwind-merge:
|
||||
specifier: ^2.5.5
|
||||
version: 2.5.5
|
||||
tailwindcss:
|
||||
specifier: ^3.4.17
|
||||
version: 3.4.17
|
||||
tailwindcss-animate:
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7
|
||||
theme-colors:
|
||||
specifier: ^0.1.0
|
||||
version: 0.1.0
|
||||
turbo:
|
||||
specifier: ^2.3.3
|
||||
version: 2.3.3
|
||||
@@ -66,15 +402,60 @@ catalogs:
|
||||
unbuild:
|
||||
specifier: ^3.0.1
|
||||
version: 3.0.1
|
||||
vee-validate:
|
||||
specifier: ^4.14.7
|
||||
version: 4.14.7
|
||||
vite:
|
||||
specifier: ^6.0.5
|
||||
version: 6.0.5
|
||||
vite-plugin-compression:
|
||||
specifier: ^0.5.1
|
||||
version: 0.5.1
|
||||
vite-plugin-dts:
|
||||
specifier: 4.2.1
|
||||
version: 4.2.1
|
||||
vite-plugin-html:
|
||||
specifier: ^3.2.2
|
||||
version: 3.2.2
|
||||
vite-plugin-lazy-import:
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7
|
||||
vite-plugin-pwa:
|
||||
specifier: ^0.21.1
|
||||
version: 0.21.1
|
||||
vite-plugin-vue-devtools:
|
||||
specifier: ^7.6.8
|
||||
version: 7.6.8
|
||||
vitest:
|
||||
specifier: ^2.1.8
|
||||
version: 2.1.8
|
||||
vue-eslint-parser:
|
||||
specifier: ^9.4.3
|
||||
version: 9.4.3
|
||||
vue-i18n:
|
||||
specifier: ^10.0.5
|
||||
version: 10.0.5
|
||||
vue-router:
|
||||
specifier: ^4.5.0
|
||||
version: 4.5.0
|
||||
vue-tsc:
|
||||
specifier: ^2.1.10
|
||||
version: 2.1.10
|
||||
vxe-pc-ui:
|
||||
specifier: ^4.3.40
|
||||
version: 4.3.40
|
||||
vxe-table:
|
||||
specifier: ^4.9.33
|
||||
version: 4.9.33
|
||||
watermark-js-plus:
|
||||
specifier: ^1.5.7
|
||||
version: 1.5.7
|
||||
zod:
|
||||
specifier: ^3.24.1
|
||||
version: 3.24.1
|
||||
zod-defaults:
|
||||
specifier: ^0.1.3
|
||||
version: 0.1.3
|
||||
|
||||
overrides:
|
||||
'@ast-grep/napi': ^0.31.1
|
||||
@@ -202,10 +583,10 @@ importers:
|
||||
version: 3.0.1(typescript@5.6.3)(vue-tsc@2.1.10(typescript@5.6.3))(vue@3.5.13(typescript@5.6.3))
|
||||
vite:
|
||||
specifier: 'catalog:'
|
||||
version: 6.0.5(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.1)(terser@5.37.0)(yaml@2.6.1)
|
||||
version: 6.0.5(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.1)(sass@1.80.6)(terser@5.37.0)(yaml@2.6.1)
|
||||
vitest:
|
||||
specifier: 'catalog:'
|
||||
version: 2.1.8(@types/node@22.10.2)(happy-dom@15.11.7)(less@4.2.1)(terser@5.37.0)
|
||||
version: 2.1.8(@types/node@22.10.2)(happy-dom@15.11.7)(less@4.2.1)(sass@1.80.6)(terser@5.37.0)
|
||||
vue:
|
||||
specifier: ^3.5.13
|
||||
version: 3.5.13(typescript@5.6.3)
|
||||
@@ -281,6 +662,9 @@ importers:
|
||||
vue-router:
|
||||
specifier: 'catalog:'
|
||||
version: 4.5.0(vue@3.5.13(typescript@5.7.2))
|
||||
xlsx:
|
||||
specifier: ^0.18.5
|
||||
version: 0.18.5
|
||||
|
||||
internal/lint-configs/commitlint-config:
|
||||
dependencies:
|
||||
@@ -2885,8 +3269,8 @@ packages:
|
||||
resolution: {integrity: sha512-bmsP4L2HqBF6i6uaMqJMcFBONVjKt+siGluRq4Ca4C0q7W2eMaVZr8iCgF9dKbcVXutftkC7D6z2SaSMmLiDyA==}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
'@intlify/shared@11.1.11':
|
||||
resolution: {integrity: sha512-RIBFTIqxZSsxUqlcyoR7iiC632bq7kkOwYvZlvcVObHfrF4NhuKc4FKvu8iPCrEO+e3XsY7/UVpfgzg+M7ETzA==}
|
||||
'@intlify/shared@11.3.0':
|
||||
resolution: {integrity: sha512-LC6P/uay7rXL5zZ5+5iRJfLs/iUN8apu9tm8YqQVmW3Uq3X4A0dOFUIDuAmB7gAC29wTHOS3EiN/IosNSz0eNQ==}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
'@intlify/shared@12.0.0-alpha.3':
|
||||
@@ -3963,6 +4347,10 @@ packages:
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
|
||||
adler-32@1.3.1:
|
||||
resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
agent-base@6.0.2:
|
||||
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
||||
engines: {node: '>= 6.0.0'}
|
||||
@@ -4304,6 +4692,10 @@ packages:
|
||||
caniuse-lite@1.0.30001690:
|
||||
resolution: {integrity: sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==}
|
||||
|
||||
cfb@1.2.2:
|
||||
resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
chai@5.1.2:
|
||||
resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -4436,6 +4828,10 @@ packages:
|
||||
codemirror@6.0.1:
|
||||
resolution: {integrity: sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==}
|
||||
|
||||
codepage@1.15.0:
|
||||
resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
color-convert@2.0.1:
|
||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||
engines: {node: '>=7.0.0'}
|
||||
@@ -5552,6 +5948,10 @@ packages:
|
||||
resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
frac@1.1.2:
|
||||
resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
fraction.js@4.3.7:
|
||||
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
||||
|
||||
@@ -8233,6 +8633,7 @@ packages:
|
||||
source-map@0.8.0-beta.0:
|
||||
resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
|
||||
engines: {node: '>= 8'}
|
||||
deprecated: The work that was done in this beta branch won't be included in future versions
|
||||
|
||||
sourcemap-codec@1.4.8:
|
||||
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
|
||||
@@ -8270,6 +8671,10 @@ packages:
|
||||
sprintf-js@1.1.3:
|
||||
resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==}
|
||||
|
||||
ssf@0.11.2:
|
||||
resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
ssri@8.0.1:
|
||||
resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==}
|
||||
engines: {node: '>= 8'}
|
||||
@@ -9247,10 +9652,18 @@ packages:
|
||||
resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
wmf@1.0.2:
|
||||
resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
word-wrap@1.2.5:
|
||||
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
word@0.3.0:
|
||||
resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==}
|
||||
engines: {node: '>=0.8'}
|
||||
|
||||
workbox-background-sync@7.3.0:
|
||||
resolution: {integrity: sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg==}
|
||||
|
||||
@@ -9330,6 +9743,11 @@ packages:
|
||||
xe-utils@3.5.32:
|
||||
resolution: {integrity: sha512-R8ZT2lRnRBQO3pchM1za/Aru+/29DVDWD/OmOFODWWGkiQYz0iVIr8Bq8uKXS6zMhEsSqVCrn46bXzfe/Agjcw==}
|
||||
|
||||
xlsx@0.18.5:
|
||||
resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==}
|
||||
engines: {node: '>=0.8'}
|
||||
hasBin: true
|
||||
|
||||
xml-name-validator@4.0.0:
|
||||
resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -9518,7 +9936,7 @@ snapshots:
|
||||
'@babel/traverse': 7.26.4
|
||||
'@babel/types': 7.26.3
|
||||
convert-source-map: 2.0.0
|
||||
debug: 4.4.0
|
||||
debug: 4.4.0(supports-color@9.4.0)
|
||||
gensync: 1.0.0-beta.2
|
||||
json5: 2.2.3
|
||||
semver: 6.3.1
|
||||
@@ -10179,7 +10597,7 @@ snapshots:
|
||||
'@babel/parser': 7.26.3
|
||||
'@babel/template': 7.25.9
|
||||
'@babel/types': 7.26.3
|
||||
debug: 4.4.0
|
||||
debug: 4.4.0(supports-color@9.4.0)
|
||||
globals: 11.12.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -11387,7 +11805,7 @@ snapshots:
|
||||
|
||||
'@intlify/shared@10.0.5': {}
|
||||
|
||||
'@intlify/shared@11.1.11': {}
|
||||
'@intlify/shared@11.3.0': {}
|
||||
|
||||
'@intlify/shared@12.0.0-alpha.3': {}
|
||||
|
||||
@@ -11395,8 +11813,8 @@ snapshots:
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0(jiti@2.4.2))
|
||||
'@intlify/bundle-utils': 10.0.0(vue-i18n@10.0.5(vue@3.5.13(typescript@5.7.2)))
|
||||
'@intlify/shared': 11.1.11
|
||||
'@intlify/vue-i18n-extensions': 7.0.0(@intlify/shared@11.1.11)(@vue/compiler-dom@3.5.13)(vue-i18n@10.0.5(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))
|
||||
'@intlify/shared': 11.3.0
|
||||
'@intlify/vue-i18n-extensions': 7.0.0(@intlify/shared@11.3.0)(@vue/compiler-dom@3.5.13)(vue-i18n@10.0.5(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))
|
||||
'@rollup/pluginutils': 5.1.4(rollup@4.28.1)
|
||||
'@typescript-eslint/scope-manager': 8.18.1
|
||||
'@typescript-eslint/typescript-estree': 8.18.1(typescript@5.7.2)
|
||||
@@ -11418,11 +11836,11 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
'@intlify/vue-i18n-extensions@7.0.0(@intlify/shared@11.1.11)(@vue/compiler-dom@3.5.13)(vue-i18n@10.0.5(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))':
|
||||
'@intlify/vue-i18n-extensions@7.0.0(@intlify/shared@11.3.0)(@vue/compiler-dom@3.5.13)(vue-i18n@10.0.5(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))':
|
||||
dependencies:
|
||||
'@babel/parser': 7.26.3
|
||||
optionalDependencies:
|
||||
'@intlify/shared': 11.1.11
|
||||
'@intlify/shared': 11.3.0
|
||||
'@vue/compiler-dom': 3.5.13
|
||||
vue: 3.5.13(typescript@5.7.2)
|
||||
vue-i18n: 10.0.5(vue@3.5.13(typescript@5.7.2))
|
||||
@@ -12406,7 +12824,7 @@ snapshots:
|
||||
'@babel/core': 7.26.0
|
||||
'@babel/plugin-transform-typescript': 7.26.3(@babel/core@7.26.0)
|
||||
'@vue/babel-plugin-jsx': 1.2.5(@babel/core@7.26.0)
|
||||
vite: 6.0.5(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.1)(terser@5.37.0)(yaml@2.6.1)
|
||||
vite: 6.0.5(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.1)(sass@1.80.6)(terser@5.37.0)(yaml@2.6.1)
|
||||
vue: 3.5.13(typescript@5.6.3)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -12418,7 +12836,7 @@ snapshots:
|
||||
|
||||
'@vitejs/plugin-vue@5.2.1(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.6.3))':
|
||||
dependencies:
|
||||
vite: 6.0.5(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.1)(terser@5.37.0)(yaml@2.6.1)
|
||||
vite: 6.0.5(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.1)(sass@1.80.6)(terser@5.37.0)(yaml@2.6.1)
|
||||
vue: 3.5.13(typescript@5.6.3)
|
||||
|
||||
'@vitest/expect@2.1.8':
|
||||
@@ -12435,15 +12853,6 @@ snapshots:
|
||||
magic-string: 0.30.17
|
||||
optionalDependencies:
|
||||
vite: 5.4.11(@types/node@22.10.2)(less@4.2.1)(sass@1.80.6)(terser@5.37.0)
|
||||
optional: true
|
||||
|
||||
'@vitest/mocker@2.1.8(vite@5.4.11(@types/node@22.10.2)(less@4.2.1)(terser@5.37.0))':
|
||||
dependencies:
|
||||
'@vitest/spy': 2.1.8
|
||||
estree-walker: 3.0.3
|
||||
magic-string: 0.30.17
|
||||
optionalDependencies:
|
||||
vite: 5.4.11(@types/node@22.10.2)(less@4.2.1)(terser@5.37.0)
|
||||
|
||||
'@vitest/pretty-format@2.1.8':
|
||||
dependencies:
|
||||
@@ -12725,6 +13134,8 @@ snapshots:
|
||||
|
||||
acorn@8.14.0: {}
|
||||
|
||||
adler-32@1.3.1: {}
|
||||
|
||||
agent-base@6.0.2:
|
||||
dependencies:
|
||||
debug: 4.4.0(supports-color@9.4.0)
|
||||
@@ -13133,6 +13544,11 @@ snapshots:
|
||||
|
||||
caniuse-lite@1.0.30001690: {}
|
||||
|
||||
cfb@1.2.2:
|
||||
dependencies:
|
||||
adler-32: 1.3.1
|
||||
crc-32: 1.2.2
|
||||
|
||||
chai@5.1.2:
|
||||
dependencies:
|
||||
assertion-error: 2.0.1
|
||||
@@ -13297,6 +13713,8 @@ snapshots:
|
||||
'@codemirror/state': 6.5.2
|
||||
'@codemirror/view': 6.36.5
|
||||
|
||||
codepage@1.15.0: {}
|
||||
|
||||
color-convert@2.0.1:
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
@@ -13717,10 +14135,6 @@ snapshots:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
debug@4.4.0:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
debug@4.4.0(supports-color@9.4.0):
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
@@ -14561,6 +14975,8 @@ snapshots:
|
||||
combined-stream: 1.0.8
|
||||
mime-types: 2.1.35
|
||||
|
||||
frac@1.1.2: {}
|
||||
|
||||
fraction.js@4.3.7: {}
|
||||
|
||||
fresh@0.5.2: {}
|
||||
@@ -15398,7 +15814,7 @@ snapshots:
|
||||
dependencies:
|
||||
chalk: 5.3.0
|
||||
commander: 12.1.0
|
||||
debug: 4.4.0
|
||||
debug: 4.4.0(supports-color@9.4.0)
|
||||
execa: 8.0.1
|
||||
lilconfig: 3.1.3
|
||||
listr2: 8.2.5
|
||||
@@ -17370,6 +17786,10 @@ snapshots:
|
||||
|
||||
sprintf-js@1.1.3: {}
|
||||
|
||||
ssf@0.11.2:
|
||||
dependencies:
|
||||
frac: 1.1.2
|
||||
|
||||
ssri@8.0.1:
|
||||
dependencies:
|
||||
minipass: 3.3.6
|
||||
@@ -18147,25 +18567,6 @@ snapshots:
|
||||
- sugarss
|
||||
- supports-color
|
||||
- terser
|
||||
optional: true
|
||||
|
||||
vite-node@2.1.8(@types/node@22.10.2)(less@4.2.1)(terser@5.37.0):
|
||||
dependencies:
|
||||
cac: 6.7.14
|
||||
debug: 4.4.0
|
||||
es-module-lexer: 1.5.4
|
||||
pathe: 1.1.2
|
||||
vite: 5.4.11(@types/node@22.10.2)(less@4.2.1)(terser@5.37.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- less
|
||||
- lightningcss
|
||||
- sass
|
||||
- sass-embedded
|
||||
- stylus
|
||||
- sugarss
|
||||
- supports-color
|
||||
- terser
|
||||
|
||||
vite-plugin-compression@0.5.1(vite@6.0.5(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.1)(sass@1.80.6)(terser@5.37.0)(yaml@2.6.1)):
|
||||
dependencies:
|
||||
@@ -18287,18 +18688,6 @@ snapshots:
|
||||
less: 4.2.1
|
||||
sass: 1.80.6
|
||||
terser: 5.37.0
|
||||
optional: true
|
||||
|
||||
vite@5.4.11(@types/node@22.10.2)(less@4.2.1)(terser@5.37.0):
|
||||
dependencies:
|
||||
esbuild: 0.24.0
|
||||
postcss: 8.4.49
|
||||
rollup: 4.28.1
|
||||
optionalDependencies:
|
||||
'@types/node': 22.10.2
|
||||
fsevents: 2.3.3
|
||||
less: 4.2.1
|
||||
terser: 5.37.0
|
||||
|
||||
vite@6.0.5(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.1)(sass@1.80.6)(terser@5.37.0)(yaml@2.6.1):
|
||||
dependencies:
|
||||
@@ -18314,19 +18703,6 @@ snapshots:
|
||||
terser: 5.37.0
|
||||
yaml: 2.6.1
|
||||
|
||||
vite@6.0.5(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.1)(terser@5.37.0)(yaml@2.6.1):
|
||||
dependencies:
|
||||
esbuild: 0.24.0
|
||||
postcss: 8.4.49
|
||||
rollup: 4.28.1
|
||||
optionalDependencies:
|
||||
'@types/node': 22.10.2
|
||||
fsevents: 2.3.3
|
||||
jiti: 2.4.2
|
||||
less: 4.2.1
|
||||
terser: 5.37.0
|
||||
yaml: 2.6.1
|
||||
|
||||
vitest@2.1.8(@types/node@22.10.2)(happy-dom@15.11.7)(less@4.2.1)(sass@1.80.6)(terser@5.37.0):
|
||||
dependencies:
|
||||
'@vitest/expect': 2.1.8
|
||||
@@ -18362,43 +18738,6 @@ snapshots:
|
||||
- sugarss
|
||||
- supports-color
|
||||
- terser
|
||||
optional: true
|
||||
|
||||
vitest@2.1.8(@types/node@22.10.2)(happy-dom@15.11.7)(less@4.2.1)(terser@5.37.0):
|
||||
dependencies:
|
||||
'@vitest/expect': 2.1.8
|
||||
'@vitest/mocker': 2.1.8(vite@5.4.11(@types/node@22.10.2)(less@4.2.1)(terser@5.37.0))
|
||||
'@vitest/pretty-format': 2.1.8
|
||||
'@vitest/runner': 2.1.8
|
||||
'@vitest/snapshot': 2.1.8
|
||||
'@vitest/spy': 2.1.8
|
||||
'@vitest/utils': 2.1.8
|
||||
chai: 5.1.2
|
||||
debug: 4.4.0
|
||||
expect-type: 1.1.0
|
||||
magic-string: 0.30.17
|
||||
pathe: 1.1.2
|
||||
std-env: 3.8.0
|
||||
tinybench: 2.9.0
|
||||
tinyexec: 0.3.1
|
||||
tinypool: 1.0.2
|
||||
tinyrainbow: 1.2.0
|
||||
vite: 5.4.11(@types/node@22.10.2)(less@4.2.1)(terser@5.37.0)
|
||||
vite-node: 2.1.8(@types/node@22.10.2)(less@4.2.1)(terser@5.37.0)
|
||||
why-is-node-running: 2.3.0
|
||||
optionalDependencies:
|
||||
'@types/node': 22.10.2
|
||||
happy-dom: 15.11.7
|
||||
transitivePeerDependencies:
|
||||
- less
|
||||
- lightningcss
|
||||
- msw
|
||||
- sass
|
||||
- sass-embedded
|
||||
- stylus
|
||||
- sugarss
|
||||
- supports-color
|
||||
- terser
|
||||
|
||||
vscode-languageserver-textdocument@1.0.12: {}
|
||||
|
||||
@@ -18575,8 +18914,12 @@ snapshots:
|
||||
dependencies:
|
||||
string-width: 7.2.0
|
||||
|
||||
wmf@1.0.2: {}
|
||||
|
||||
word-wrap@1.2.5: {}
|
||||
|
||||
word@0.3.0: {}
|
||||
|
||||
workbox-background-sync@7.3.0:
|
||||
dependencies:
|
||||
idb: 7.1.1
|
||||
@@ -18725,6 +19068,16 @@ snapshots:
|
||||
|
||||
xe-utils@3.5.32: {}
|
||||
|
||||
xlsx@0.18.5:
|
||||
dependencies:
|
||||
adler-32: 1.3.1
|
||||
cfb: 1.2.2
|
||||
codepage: 1.15.0
|
||||
crc-32: 1.2.2
|
||||
ssf: 0.11.2
|
||||
wmf: 1.0.2
|
||||
word: 0.3.0
|
||||
|
||||
xml-name-validator@4.0.0: {}
|
||||
|
||||
xss@1.0.15:
|
||||
|
||||
Reference in New Issue
Block a user