条码签收

This commit is contained in:
wyuu 2026-01-29 17:49:16 +08:00
parent 22a614959e
commit 8d6f27e377
8 changed files with 483 additions and 43 deletions

View File

@ -62,12 +62,15 @@
"eslint-plugin-auto-import": "^0.1.1", "eslint-plugin-auto-import": "^0.1.1",
"eslint-plugin-vue": "^10.1.0", "eslint-plugin-vue": "^10.1.0",
"globals": "^16.1.0", "globals": "^16.1.0",
"rollup-plugin-visualizer": "^6.0.5",
"sass": "1.69.5", "sass": "1.69.5",
"terser": "^5.46.0",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"unplugin-auto-import": "0.17.1", "unplugin-auto-import": "0.17.1",
"unplugin-vue-setup-extend-plus": "1.0.0", "unplugin-vue-setup-extend-plus": "1.0.0",
"vite": "5.0.4", "vite": "5.0.4",
"vite-plugin-compression": "0.5.1", "vite-plugin-compression": "0.5.1",
"vite-plugin-imagemin": "^0.6.1",
"vite-plugin-svg-icons": "2.0.1" "vite-plugin-svg-icons": "2.0.1"
} }
} }

View File

@ -439,5 +439,37 @@ export function clearPrintflag(query?: Object) {
params: query params: query
}) })
} }
// 自动签收条码
export function autosavebarcode(query?: Object) {
return request({
url: '/liswork/autosavebarcode',
method: 'get',
params: query
})
}
// 条码签收
export function querybarcode(query?: Object) {
return request({
url: '/liswork/querybarcode',
method: 'get',
params: query
})
}
// 拒收条码
export function refusedbarcode(query?: Object) {
return request({
url: '/refused/getData',
method: 'get',
params: query
})
}
// 保存拒收条码
export function refusedSaveData(query?: Object) {
return request({
url: '/refused/saveData',
method: 'post',
data: query
})
}

View File

@ -62,9 +62,9 @@
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="info" :size="aotuSize" plain @click="closeHadnle">取消登记</el-button> <el-button type="info" :size="aotuSize" plain @click="closeHadnle">取消登记</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <!-- <el-col :span="1.5">
<el-button type="warning" :size="aotuSize" plain @click="openBlock('送检登记')">送检登记</el-button> <el-button type="warning" :size="aotuSize" plain @click="openBlock('送检登记')">送检登记</el-button>
</el-col> </el-col> -->
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="warning" :size="aotuSize" plain @click="goReport">报告查询</el-button> <el-button type="warning" :size="aotuSize" plain @click="goReport">报告查询</el-button>
</el-col> </el-col>
@ -137,18 +137,16 @@
<!-- 采样登记 --> <!-- 采样登记 -->
<el-dialog v-model="dialogVisible" :title="title" draggable :close-on-click-modal="false" width="70vw" <el-dialog v-model="dialogVisible" :title="title" draggable :close-on-click-modal="false" width="70vw"
@close="closeDialog"> @close="closeDialog">
<div class="flex-between"> <el-row :gutter="10" class="mb8">
<el-row :gutter="10" class="mb8"> <el-col :span="4">
<el-col :span="1.5"> <el-input ref="sqhRef" v-model="sqhText" clearable placeholder="条形码" @keyup.enter="sqdQuery"
<el-input ref="sqhRef" v-model="sqhText" clearable placeholder="条形码" @keyup.enter="sqdQuery" @clear="sqdQuery" />
@clear="sqdQuery" /> </el-col>
</el-col> <el-col :span="1.5">
<el-col :span="1.5"> <el-button type="primary" @click="sqdQuery" plain>读取</el-button>
<el-button type="primary" @click="sqdQuery" plain>读取</el-button> </el-col>
</el-col> </el-row>
</el-row>
<!-- <el-button type="primary" plain>保存</el-button> -->
</div>
<CustomTable :data="cyTableData" :columns="cyColumns" :config="cyTableConfig"> <CustomTable :data="cyTableData" :columns="cyColumns" :config="cyTableConfig">
<template #zt="{ row }"> <template #zt="{ row }">
{{ formatDict(row.zt, 'ST') }} {{ formatDict(row.zt, 'ST') }}
@ -518,8 +516,8 @@ const sqdQuery = () => {
userid: queryParams.userid, userid: queryParams.userid,
status: 12, status: 12,
yljg: queryParams.yljg yljg: queryParams.yljg
}).then((res: any) => { }).then((res2: any) => {
if (res.code == 0) { if (res2.code == 0) {
cyTableData.value = cyTableData.value.concat(res.data) cyTableData.value = cyTableData.value.concat(res.data)
} }
}) })
@ -535,6 +533,7 @@ const sqdQuery = () => {
const closeDialog = () => { const closeDialog = () => {
cyTableData.value = [] cyTableData.value = []
sqhText.value = '' sqhText.value = ''
handleQuery()
} }
@ -611,6 +610,7 @@ const sendSampleHandle = () => {
pdfUrl.value = `data:application/pdf;base64,${url}` pdfUrl.value = `data:application/pdf;base64,${url}`
previewShow.value = true previewShow.value = true
} }
handleQuery()
}) })
} }
@ -705,10 +705,8 @@ const printHandle = () => {
} }
addObj(data).then((res: any) => { addObj(data).then((res: any) => {
if (res.code == 0) {
getList()
}
}).finally(() => { }).finally(() => {
getList()
btnLoading.value = false; btnLoading.value = false;
}) })
} }

View File

@ -662,14 +662,10 @@ const changeStatus = (updatedPat: any, flag: boolean) => {
labPat.value = response.data; labPat.value = response.data;
const index = labPatList.value.findIndex((item: any) => item.ybh == updatedPat.ybh); const index = labPatList.value.findIndex((item: any) => item.ybh == updatedPat.ybh);
if (index !== -1) { if (index !== -1) {
labPatList.value = labPatList.value.map((item, i) => // 更新样本列表中的样本信息
i === index ? { ...labPat.value } : item labPatList.value = labPatList.value.map((item, i) => i === index ? { ...labPat.value } : item);
);
highlightRowIndex.value = index; highlightRowIndex.value = index;
nextTick(() => {
labPatListRef.value.setCurrentRow(labPat.value);
});
// 条码号输入后操作 // 条码号输入后操作
if (flag) { if (flag) {
setTimeout(() => { handleNext() }, 10) setTimeout(() => { handleNext() }, 10)
@ -823,7 +819,7 @@ onMounted(async () => {
GMC: toRaw(dictRefs.GMC.value) || [], GMC: toRaw(dictRefs.GMC.value) || [],
}; };
// 初始化Socket // 初始化Socket
initSocket() // initSocket()
}); });
onActivated(() => { onActivated(() => {

View File

@ -0,0 +1,188 @@
/**
* @file index.vue
* @author: w
* @since: 2026-01-28
*/
<template>
<div class="app-container">
<el-row :gutter="10" class="mb8">
<el-col :span="4">
<el-input ref="sqhRef" v-model="sqhText" clearable placeholder="条形码" @keyup.enter="sqdQuery"
@clear="sqdQuery" />
</el-col>
<el-col :span="1.5">
<el-button type="primary" @click="sqdQuery" plain>读取</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain>保存</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" @click="setHandle" plain>设置</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain>打印</el-button>
</el-col>
</el-row>
<div class="table-main">
<CustomTable :data="tableData" :columns="columns" :config="tableConfig" @selection-change="handleSelectionChange"
:enable-column-drag="true" @column-drag-end="handleColumnDragEnd">
<template #jzbz="{ row }">
<div style="color: #f00;" v-if="row.jzbz == '1'">急</div>
<div style="color: transparent;" v-else>无</div>
</template>
<template #zt="{ row }">
{{ formatDict(row.zt.trim(), 'ST') }}
</template>
<template #ksdh="{ row }">
{{ formatDict(row.ksdh, 'DP') }}
</template>
<template #brxb="{ row }">
{{ formatDict(row.brxb, 'SX') }}
</template>
<template #sqys="{ row }">
{{ formatYs(row.sqys) }}
</template>
</CustomTable>
</div>
<el-dialog v-model="dialogVisible" title="设置" draggable :close-on-click-modal="false" width="40vw">
<el-row>
<el-col :span="12" v-for="(item, index) in setList" :key="index" class="mb8">
<template v-if="item.configOptiontype == 0">
<el-checkbox v-model="item.configDefvalue" :label="item.configName" true-value="1" false-value="0" />
</template>
<template v-if="item.configOptiontype == 1">
{{ item.configName }}: <el-select v-model="item.configDefvalue" placeholder="请选择" style="width: 150px;">
<el-option v-for="(item, index) in item.remark" :key="index" :label="item.label" :value="item.value" />
</el-select>
</template>
</el-col>
</el-row>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="subHandle">保 存</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { querybarcode, autosavebarcode } from '@/api/liswork/work/LisWork';
import { paramList, updateParam } from '@/api/liswork/xtwh/ComOpt'
import { formatDict, getDictData } from '@/hooks'
import { ElMessage } from 'element-plus'
import { listUser } from '@/api/system/user.js'
const sqhRef = useTemplateRef('sqhRef');
const sqhText = ref('');
const dialogVisible = ref(false);
const tableData = ref([]);
const columns = ref([
{ type: 'selection', width: 30, visible: true, align: 'center' },
{ label: '急诊', prop: 'jzbz', width: 50, visible: true, slot: 'jzbz' },
{ label: '类别', prop: 'bgddh', visible: true, },
{ label: '标本', prop: 'yblx', visible: true, width: 60, align: 'center' },
{ label: '申请科室', prop: 'ksdh', visible: true, slot: 'ksdh' },
{ label: '床号', prop: 'ch', visible: true, width: 50, align: 'center' },
{ label: '病历号', prop: 'brdh', visible: true, },
{ label: '病历号', prop: 'brdh', visible: true, },
{ label: '姓名', prop: 'brxm', visible: true, width: 40, align: 'center' },
{ label: '性别', prop: 'brxb', visible: true, slot: 'brxb', width: 40, align: 'center' },
{ label: '申请号/条码', prop: 'sqh', visible: true, width: 100, align: 'center' },
{ label: '申请项目', prop: 'jymd', visible: true, width: 200, align: 'center' },
{ label: '签收状态', prop: 'zt', visible: true, slot: 'zt' },
{ label: '拒签理由', prop: 'bz3', visible: true, },
{ label: '申请医生', prop: 'sqys', visible: true, slot: 'sqys' },
{ label: '采样人', prop: 'cyr', visible: true, },
{ label: '标本送出人', prop: 'bbsjrname', visible: true, },
{ label: '申请时间', prop: 'sqsj', visible: true, },
{ label: '采样时间', prop: 'cyblsj', visible: true, },
{ label: '标本送出时间', prop: 'sjsj', visible: true, width: 100, },
{ label: '诊断', prop: 'zd', visible: true, },
])
const tableConfig = {
border: true,
highlightCurrentRow: true,
height: '100%',
};
const handleColumnDragEnd = (data) => {
console.log('data==>', data);
columns.value = data.columns;
}
const sqdQuery = () => {
const index = tableData.value.findIndex((item) => item.sqh == sqhText.value)
if (index !== -1) return ElMessage.warning('该申请单数据已存在!')
querybarcode({ sqh: sqhText.value }).then((res) => {
if (res.code == 0 && res.data) {
tableData.value = tableData.value.concat(res.data)
}
}).finally(() => {
sqhText.value = ''
nextTick(() => {
sqhRef.value?.focus()
})
})
}
const handleSelectionChange = (selection) => {
console.log("🚀 ~ handleSelectionChange ~ selection:", selection)
}
const setList = ref([])
const setHandle = () => {
dialogVisible.value = true
}
const subHandle = () => {
let arr = JSON.parse(JSON.stringify(setList.value))
arr.forEach(e => {
if (e.configOptiontype == 1) {
e.remark = JSON.stringify(e.remark)
}
});
updateParam(arr).then((res) => {
if (res.code == 0) {
ElMessage.success('设置保存成功!')
dialogVisible.value = false
}
})
}
const formatYs = (v) => {
return userList.value.find(item => item.userId == v)?.nickName || v
}
const userList = ref([])
onMounted(() => {
getDictData('ST', 'SX', 'DP')
const data = { status: 0, del_flag: 0, pageSize: 1000, pageNum: 1 }
listUser(data).then((res) => {
userList.value = res.rows;
});
paramList({ yq: '_BAR_', optiontype: 'bar' }).then((res) => {
res.data.forEach(e => {
if (e.configOptiontype == 1) {
e.remark = JSON.parse(e.remark)
}
});
setList.value = res.data
})
})
</script>
<style scoped lang="scss">
.table-main {
height: calc(100% - 50px);
}
</style>

View File

@ -0,0 +1,165 @@
/**
* @file index.vue
* @author: w
* @since: 2026-01-28
*/
<template>
<div class="app-container">
<el-row :gutter="10" class="mb8">
<el-col :span="4">
<el-input ref="sqhRef" v-model="sqhText" clearable placeholder="条形码" @keyup.enter="sqdQuery"
@clear="sqdQuery" />
</el-col>
<el-col :span="1.5">
<el-button type="primary" @click="sqdQuery" plain>读取</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain @click="saveData">保存</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain>打印</el-button>
</el-col>
</el-row>
<div class="table-main">
<CustomTable :data="tableData" :columns="columns" :config="tableConfig" @selection-change="handleSelectionChange"
:enable-column-drag="true" @column-drag-end="handleColumnDragEnd">
<template #mode="{ row }">
<SelectTable v-model:data="row.mode" :tableData="regModeList" class="full-width-input" />
</template>
<template #refuseText="{ row }">
<SelectTable v-model:data="row.refuseText" dictType='JQLY' class="full-width-input" />
</template>
<template #description="{ row }">
<SelectTable v-model:data="row.description" dictType='BCMS' class="full-width-input" />
</template>
<template #jzbz="{ row }">
<div style="color: #f00;" v-if="row.jzbz == '1'">急</div>
<div style="color: transparent;" v-else>无</div>
</template>
<template #zt="{ row }">
{{ formatDict(row.zt.trim(), 'ST') }}
</template>
<template #ksdh="{ row }">
{{ formatDict(row.ksdh, 'DP') }}
</template>
<template #brxb="{ row }">
{{ formatDict(row.brxb, 'SX') }}
</template>
<template #sqys="{ row }">
{{ formatYs(row.sqys) }}
</template>
</CustomTable>
</div>
<!-- 校验用户 -->
<CheckUser ref="checkUserRef" @onConfirm="handleCheckUserConfirm" />
</div>
</template>
<script setup>
import { refusedbarcode, refusedSaveData } from '@/api/liswork/work/LisWork';
import { formatDict, getDictData } from '@/hooks'
import { ElMessage } from 'element-plus'
import { listUser } from '@/api/system/user.js'
import CheckUser from "@/views/liswork/work/components/CheckUser.vue";
const { proxy } = getCurrentInstance();
const { reg_mode } = proxy.useDict("reg_mode"); //参数类别
const regModeList = reg_mode
const sqhRef = useTemplateRef('sqhRef');
const checkUserRef = useTemplateRef('checkUserRef');
const sqhText = ref('');
const tableData = ref([]);
const columns = ref([
{ type: 'selection', width: 30, visible: true, align: 'center' },
{ label: '登记模式', prop: 'mode', width: 120, visible: true, slot: 'mode' },
{ label: '不合格类别', prop: 'refuseText', width: 120, visible: true, slot: 'refuseText' },
{ label: '补充描述', prop: 'description', width: 120, visible: true, slot: 'description' },
{ label: '急诊', prop: 'jzbz', width: 50, visible: true, slot: 'jzbz' },
{ label: '类别', prop: 'bgdjc', visible: true, },
{ label: '标本', prop: 'yblx', visible: true, width: 60, align: 'center' },
{ label: '申请科室', prop: 'ksdh', visible: true, slot: 'ksdh' },
{ label: '床号', prop: 'ch', visible: true, width: 50, align: 'center' },
{ label: '病历号', prop: 'brdh', visible: true, },
{ label: '病历号', prop: 'brdh', visible: true, },
{ label: '姓名', prop: 'brxm', visible: true, width: 40, align: 'center' },
{ label: '性别', prop: 'brxb', visible: true, slot: 'brxb', width: 40, align: 'center' },
{ label: '申请号/条码', prop: 'sqh', visible: true, width: 100, align: 'center' },
{ label: '申请项目', prop: 'cp_item', visible: true, width: 200, align: 'center' },
{ label: '签收状态', prop: 'zt', visible: true, slot: 'zt' },
{ label: '申请医生', prop: 'sqys', visible: true, slot: 'sqys' },
{ label: '采样人', prop: 'cyr', visible: true, },
{ label: '标本送出人', prop: 'bbsjrname', visible: true, },
{ label: '申请时间', prop: 'sqsj', visible: true, },
{ label: '采样时间', prop: 'cyblsj', visible: true, },
{ label: '标本送出时间', prop: 'sjsj', visible: true, width: 100, },
{ label: '诊断', prop: 'zd', visible: true, },
])
const tableConfig = {
border: true,
highlightCurrentRow: true,
height: '100%',
};
const handleColumnDragEnd = (data) => {
columns.value = data.columns;
}
const sqdQuery = () => {
const index = tableData.value.findIndex((item) => item.sqh == sqhText.value)
if (index !== -1) return ElMessage.warning('该申请单数据已存在!')
refusedbarcode({ sqh: sqhText.value }).then((res) => {
if (res.code == 0 && res.data) {
tableData.value = tableData.value.concat(res.data)
}
}).finally(() => {
sqhText.value = ''
nextTick(() => {
sqhRef.value?.focus()
})
})
}
const handleSelectionChange = (selection) => {
console.log("🚀 ~ handleSelectionChange ~ selection:", selection)
}
const saveData = () => {
const flag = tableData.value.every(item => item.mode && item.refuseText && item.description)
if (!flag) return ElMessage.warning('请填写完整拒收信息!')
checkUserRef.value.open()
}
const handleCheckUserConfirm = (info) => {
tableData.value = tableData.value.map(item => ({
...item,
tzr: info.yhdh,
}))
refusedSaveData(tableData.value).then((res) => {
ElMessage.success(res.msg)
})
}
const formatYs = (v) => {
return userList.value.find(item => item.userId == v)?.nickName || v
}
const userList = ref([])
onMounted(() => {
getDictData('ST', 'SX', 'DP')
const data = { status: 0, del_flag: 0, pageSize: 1000, pageNum: 1 }
listUser(data).then((res) => {
userList.value = res.rows;
});
})
</script>
<style scoped lang="scss">
.table-main {
height: calc(100% - 50px);
}
</style>

View File

@ -543,16 +543,17 @@ const changeStatus = (updatedPat: any, flag: boolean) => {
queryLabPat(queryParams.value).then((response: any) => { queryLabPat(queryParams.value).then((response: any) => {
if (response.code == 0) { if (response.code == 0) {
labPat.value = response.data; labPat.value = response.data;
lastRow.value = response.data
const index = labPatList.value.findIndex((item: any) => item.ybh == updatedPat.ybh); const index = labPatList.value.findIndex((item: any) => item.ybh == updatedPat.ybh);
if (index !== -1) { if (index !== -1) {
labPatList.value = labPatList.value.map((item, i) => // 更新列表中对应的样本信息
i === index ? { ...labPat.value } : item labPatList.value = labPatList.value.map((item, i) => i === index ? { ...labPat.value } : item);
);
highlightRowIndex.value = index; highlightRowIndex.value = index;
nextTick(() => { // nextTick(() => {
labPatListRef.value.setCurrentRow(labPat.value); // labPatListRef.value.setCurrentRow(labPat.value);
}); // });
// 条码号输入后操作 // 条码号输入后操作
if (flag) { if (flag) {
setTimeout(() => { handleNext() }, 10) setTimeout(() => { handleNext() }, 10)
@ -708,7 +709,7 @@ onMounted(async () => {
ST: toRaw(dictRefs.ST.value) || [], ST: toRaw(dictRefs.ST.value) || [],
}; };
// 初始化Socket // 初始化Socket
initSocket() // initSocket()
}); });
onActivated(() => { onActivated(() => {

View File

@ -4,7 +4,10 @@ import {
} from 'vite' } from 'vite'
import path from 'path' import path from 'path'
import createVitePlugins from './vite/plugins' import createVitePlugins from './vite/plugins'
import.meta import viteImagemin from 'vite-plugin-imagemin'
import {
visualizer
} from 'rollup-plugin-visualizer'
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig(({ export default defineConfig(({
@ -20,7 +23,28 @@ export default defineConfig(({
// 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上 // 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。 // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
base: VITE_APP_ENV === 'production' ? '/' : '/', base: VITE_APP_ENV === 'production' ? '/' : '/',
plugins: createVitePlugins(env, command === 'build'), plugins: [
createVitePlugins(env, command === 'build'),
// 图片压缩
VITE_APP_ENV === 'production' && viteImagemin({
gifsicle: {
optimizationLevel: 3
},
optipng: {
optimizationLevel: 7
},
mozjpeg: {
quality: 85
},
svgo: {
plugins: [{
removeViewBox: false
}, {
cleanupIDs: false
}]
}
})
].filter(Boolean),
resolve: { resolve: {
// https://cn.vitejs.dev/config/#resolve-alias // https://cn.vitejs.dev/config/#resolve-alias
alias: { alias: {
@ -69,21 +93,54 @@ export default defineConfig(({
}] }]
} }
}, },
// 新增build配置,用于生产环境移除console
build: { build: {
// 只有生产环境才移除console minify: VITE_APP_ENV === 'production' ? 'terser' : 'esbuild',
minify: VITE_APP_ENV === 'production' ? 'esbuild' : 'terser', terserOptions: VITE_APP_ENV === 'production' ? {
compress: {
drop_console: true,
drop_debugger: true,
pure_funcs: ['console.log', 'console.warn'],
collapse_vars: true,
reduce_vars: true
},
format: {
comments: false
}
} : {},
esbuild: { esbuild: {
// 生产环境下移除console和debugger
drop: VITE_APP_ENV === 'production' ? ['console', 'debugger'] : [] drop: VITE_APP_ENV === 'production' ? ['console', 'debugger'] : []
}, },
target: 'es2015', target: 'es2015',
cssTarget: ['chrome64', 'firefox67', 'safari11.1', 'edge79'] // CSS兼容目标: ['chrome64', 'firefox67', 'safari11.1', 'edge79'] // CSS兼容目标 cssTarget: ['chrome64', 'firefox67', 'safari11.1', 'edge79'],
assetsInlineLimit: 4096,
chunkSizeWarningLimit: 500,
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) return 'vendor';
if (id.includes('src/components/common')) return 'common-components';
if (id.includes('src/utils')) return 'utils';
},
preload: false,
prefetch: false,
chunkFileNames: 'js/[name]-[hash].js',
entryFileNames: 'js/[name]-[hash].js',
assetFileNames: '[ext]/[name]-[hash].[ext]'
},
plugins: [
VITE_APP_ENV === 'production' && visualizer({
filename: './node_modules/.cache/visualizer/stats.html',
open: true,
gzipSize: true,
brotliSize: true
})
].filter(Boolean)
}
}, },
optimizeDeps: { optimizeDeps: {
// include: ['jquery', 'select2', 'vue3-select2-component'], include: ['vue', 'axios'], // 仅预构建核心依赖
// exclude: ['sortablejs'] // 跳过 Vite 对 SortableJS 的预构建 exclude: ['sortablejs', 'jquery']
}, }
} }
}) })