修改页面

This commit is contained in:
my_ong 2024-12-02 20:25:57 +08:00
parent 6ebf253598
commit 73df90e8ae
35 changed files with 2523 additions and 580 deletions

438
.commitlintrc.cjs Normal file
View File

@ -0,0 +1,438 @@
module.exports = {
// 继承的规则
extends: ['@commitlint/config-conventional'],
// 定义规则类型
rules: {
// type 类型定义表示git提交的type必须在以下类型范围内
'type-enum': [
2,
'always',
[
'art', //结构改进 / 格式化代码
'zap', //性能改善
'fire', //删除代码或者文件
'bug', //修了一个 BUG
'ambulance', //重大热修复
'sparkles', //引入新的特性
'pencil', //写文档
'rocket', //部署相关
'lipstick', //更新界面与样式文件
'tada', //创世提交
'white_check_mark', //更新测试
'lock', //修复安全问题
'apple', //修复在苹果系统上的问题
'penguin', //修复在 Linux 系统上的问题
'checkered_flag', //修复在 Windows 系统上的问题
'robot', //修复在安卓系统上的问题
'green_apple', //修复在 iOS 系统上的问题
'bookmark', //发布 / 版本标
'rotating_light', //消除 linter 警告
'construction', //进行中
'green_heart', //修复持续集成构建
'arrow_down', //降级依赖
'arrow_up', //升级依赖
'pushpin', //固定依赖在特定的版本
'construction_worker', //添加持续集成构建系统
'chart_with_upwards_trend', //添加分析或者跟踪代码
'recycle', //代码重构
'whale', //Docker 容器相关
'heavy_plus_sign', //添加依赖
'heavy_minus_sign', //删除依赖
'wrench', //改变配置文件
'globe_with_meridians', //国际化与本地化
'pencil2', //修正拼写错误
'poop', //写需要改进的坏代码
'rewind', //回滚改动
'twisted_rightwards_arrows', //合并分支
'package', //更新编译后的文件或者包
'alien', //由于外部 API 变动而更新代码
'truck', //文件移动或者重命名
'page_facing_up', //添加或者更新许可
'boom', //引入破坏性的改动
'bento', //添加或者更新静态资源
'ok_hand', //代码审核后更新代码
'wheelchair', //改进可访问性
'bulb', //给源代码加文档
'beers', //醉写代码
'speech_balloon', //更新文本和字面
'card_file_box', //执行数据库相关的改动
'loud_sound', //添加日志
'mute', //删除日志
'busts_in_silhouette', //添加贡献者(们)
'children_crossing', //改进用户体验 / 可用性
'building_construction', //架构改动
'iphone', //响应性设计相关
'clown_face', //模拟相关
'egg', //添加一个彩蛋
'see_no_evil', //添加或者更新 .gitignore 文件
'camera_flash', //添加或者更新快照
'alembic', //研究新事物
'mag', //改进搜索引擎优化
'wheel_of_dharma', //Kubernetes 相关的工作
'label', //添加或者更新类型Flow, TypeScript
],
],
// subject 大小写不做校验
'subject-case': [0],
},
prompt: {
messages: {
type: '选择你要提交的类型 :',
scope: '选择一个提交范围(可选):',
customScope: '请输入自定义的提交范围 :',
subject: '填写简短精炼的变更描述 :\n',
body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
footerPrefixesSelect: '选择关联issue前缀(可选):',
customFooterPrefix: '输入自定义issue前缀 :',
footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
generatingByAI: '正在通过 AI 生成你的提交简短描述...',
generatedSelectByAI: '选择一个 AI 生成的简短描述:',
confirmCommit: '是否提交或修改commit ?',
},
types: [
{
value: 'sparkles',
name: '✨ 引入新的特性',
emoji: ':sparkles:',
},
{
value: 'bug',
name: '🐛 修了一个 BUG',
emoji: ':bug:',
},
{
value: 'lipstick',
name: '💄 更新界面与样式文件',
emoji: ':lipstick:',
},
{
value: 'construction',
name: '🚧 进行中',
emoji: ':construction:',
},
{
value: 'tada',
name: '🎉 创世提交',
emoji: ':tada:',
},
{
value: 'art',
name: '🎨 结构改进 / 格式化代码',
emoji: ':art:',
},
{
value: 'zap',
name: '⚡️ 性能改善',
emoji: ':zap:',
},
{
value: 'label',
name: '🏷️ 添加或者更新类型(Flow, TypeScript)',
emoji: ':label:',
},
{
value: 'pencil',
name: '📝 写文档',
emoji: ':pencil:',
},
{
value: 'fire',
name: '🔥 删除代码或者文件',
emoji: ':fire:',
},
{
value: 'rotating_light',
name: '🚨 消除 linter 警告',
emoji: ':rotating_light:',
},
{
value: 'wrench',
name: '🔧 改变配置文件',
emoji: ':wrench:',
},
{
value: 'globe_with_meridians',
name: '🌐 国际化与本地化',
emoji: ':globe_with_meridians:',
},
{
value: 'pencil2',
name: '✏️ 修正拼写错误',
emoji: ':pencil2:',
},
{
value: 'poop',
name: '💩 写需要改进的坏代码',
emoji: ':poop:',
},
{
value: 'rewind',
name: '⏪ 回滚改动',
emoji: ':rewind:',
},
{
value: 'twisted_rightwards_arrows',
name: '🔀 合并分支',
emoji: ':twisted_rightwards_arrows:',
},
{
value: 'heavy_plus_sign',
name: ' 添加依赖',
emoji: ':heavy_plus_sign:',
},
{
value: 'heavy_minus_sign',
name: ' 删除依赖',
emoji: ':heavy_minus_sign:',
},
{
value: 'arrow_down',
name: '⬇️ 降级依赖',
emoji: ':arrow_down:',
},
{
value: 'arrow_up',
name: '⬆️ 升级依赖',
emoji: ':arrow_up:',
},
{
value: 'pushpin',
name: '📌 固定依赖在特定的版本',
emoji: ':pushpin:',
},
{
value: 'bookmark',
name: '🔖 发布 / 版本标',
emoji: ':bookmark:',
},
{
value: 'ambulance',
name: '🚑 重大热修复',
emoji: ':ambulance:',
},
{
value: 'rocket',
name: '🚀 部署相关',
emoji: ':rocket:',
},
{
value: 'white_check_mark',
name: '✅ 更新测试',
emoji: ':white_check_mark:',
},
{
value: 'lock',
name: '🔒 修复安全问题',
emoji: ':lock:',
},
{
value: 'apple',
name: '🍎 修复在苹果系统上的问题',
emoji: ':apple:',
},
{
value: 'penguin',
name: '🐧 修复在 Linux 系统上的问题',
emoji: ':penguin:',
},
{
value: 'checkered_flag',
name: '🏁 修复在 Windows 系统上的问题',
emoji: ':checkered_flag:',
},
{
value: 'robot',
name: '🤖 修复在安卓系统上的问题',
emoji: ':robot:',
},
{
value: 'green_apple',
name: '🍏 修复在 iOS 系统上的问题',
emoji: ':green_apple:',
},
{
value: 'green_heart',
name: '💚 修复持续集成构建',
emoji: ':green_heart:',
},
{
value: 'construction_worker',
name: '👷 添加持续集成构建系统',
emoji: ':construction_worker:',
},
{
value: 'chart_with_upwards_trend',
name: '📈 添加分析或者跟踪代码',
emoji: ':chart_with_upwards_trend:',
},
{
value: 'recycle',
name: '♻️ 代码重构',
emoji: ':recycle:',
},
{
value: 'whale',
name: '🐳 Docker 容器相关',
emoji: ':whale:',
},
{
value: 'package',
name: '📦 更新编译后的文件或者包',
emoji: ':package:',
},
{
value: 'alien',
name: '👽 由于外部 API 变动而更新代码',
emoji: ':alien:',
},
{
value: 'truck',
name: '🚚 文件移动或者重命名',
emoji: ':truck:',
},
{
value: 'page_facing_up',
name: '📄 添加或者更新许可',
emoji: ':page_facing_up:',
},
{
value: 'boom',
name: '💥 引入破坏性的改动',
emoji: ':boom:',
},
{
value: 'bento',
name: '🍱 添加或者更新静态资源',
emoji: ':bento:',
},
{
value: 'ok_hand',
name: '👌 代码审核后更新代码',
emoji: ':ok_hand:',
},
{
value: 'wheelchair',
name: '♿️ 改进可访问性',
emoji: ':wheelchair:',
},
{
value: 'bulb',
name: '💡 给源代码加文档',
emoji: ':bulb:',
},
{
value: 'beers',
name: '🍻 醉写代码',
emoji: ':beers:',
},
{
value: 'speech_balloon',
name: '💬 更新文本和字面',
emoji: ':speech_balloon:',
},
{
value: 'card_file_box',
name: '🗃 执行数据库相关的改动',
emoji: ':card_file_box:',
},
{
value: 'loud_sound',
name: '🔊 添加日志',
emoji: ':loud_sound:',
},
{
value: 'mute',
name: '🔇 删除日志',
emoji: ':mute:',
},
{
value: 'busts_in_silhouette',
name: '👥 添加贡献者(们)',
emoji: ':busts_in_silhouette:',
},
{
value: 'children_crossing',
name: '🚸 改进用户体验 / 可用性',
emoji: ':children_crossing:',
},
{
value: 'building_construction',
name: '🏗 架构改动',
emoji: ':building_construction:',
},
{
value: 'iphone',
name: '📱 响应性设计相关',
emoji: ':iphone:',
},
{
value: 'clown_face',
name: '🤡 模拟相关',
emoji: ':clown_face:',
},
{
value: 'egg',
name: '🥚 添加一个彩蛋',
emoji: ':egg:',
},
{
value: 'see_no_evil',
name: '🙈 添加或者更新 .gitignore 文件',
emoji: ':see_no_evil:',
},
{
value: 'camera_flash',
name: '📸 添加或者更新快照',
emoji: ':camera_flash:',
},
{
value: 'alembic',
name: '⚗ 研究新事物',
emoji: ':alembic:',
},
{
value: 'mag',
name: '🔍 改进搜索引擎优化',
emoji: ':mag:',
},
{
value: 'wheel_of_dharma',
name: '☸️ Kubernetes 相关的工作',
emoji: ':wheel_of_dharma:',
},
],
useEmoji: true,
emojiAlign: 'center',
useAI: false,
aiNumber: 1,
themeColorCode: '',
scopes: [],
allowCustomScopes: true,
allowEmptyScopes: true,
customScopesAlign: 'bottom',
customScopesAlias: 'custom',
emptyScopesAlias: 'empty',
upperCaseSubject: false,
markBreakingChangeMode: false,
allowBreakingChanges: ['feat', 'fix'],
breaklineNumber: 100,
breaklineChar: '|',
skipQuestions: [],
issuePrefixes: [{ value: 'closed', name: 'closed: ISSUES has been processed' }],
customIssuePrefixAlign: 'top',
emptyIssuePrefixAlias: 'skip',
customIssuePrefixAlias: 'custom',
allowCustomIssuePrefix: true,
allowEmptyIssuePrefix: true,
confirmColorize: true,
maxHeaderLength: Infinity,
maxSubjectLength: Infinity,
minSubjectLength: 0,
scopeOverrides: undefined,
defaultBody: '',
defaultIssues: '',
defaultScope: '',
defaultSubject: '',
},
}

11
.editorconfig Normal file
View File

@ -0,0 +1,11 @@
# Editor configuration, see http://editorconfig.org
# 表示是最顶层的 EditorConfig 配置文件
root = true
[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格tab | space
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行首的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行
trim_trailing_whitespace = true # 删除一行中的前后空格

1
.env Normal file
View File

@ -0,0 +1 @@
VITE_HTTP_PREFIX='/api'

297
.eslintrc-auto-import.json Normal file
View File

@ -0,0 +1,297 @@
{
"globals": {
"Component": true,
"ComponentPublicInstance": true,
"ComputedRef": true,
"EffectScope": true,
"ExtractDefaultPropTypes": true,
"ExtractPropTypes": true,
"ExtractPublicPropTypes": true,
"InjectionKey": true,
"PropType": true,
"Ref": true,
"VNode": true,
"WritableComputedRef": true,
"computed": true,
"createApp": true,
"customRef": true,
"defineAsyncComponent": true,
"defineComponent": true,
"effectScope": true,
"getCurrentInstance": true,
"getCurrentScope": true,
"h": true,
"inject": true,
"isProxy": true,
"isReactive": true,
"isReadonly": true,
"isRef": true,
"markRaw": true,
"nextTick": true,
"onActivated": true,
"onBeforeMount": true,
"onBeforeRouteLeave": true,
"onBeforeRouteUpdate": true,
"onBeforeUnmount": true,
"onBeforeUpdate": true,
"onDeactivated": true,
"onErrorCaptured": true,
"onMounted": true,
"onRenderTracked": true,
"onRenderTriggered": true,
"onScopeDispose": true,
"onServerPrefetch": true,
"onUnmounted": true,
"onUpdated": true,
"provide": true,
"reactive": true,
"readonly": true,
"ref": true,
"resolveComponent": true,
"shallowReactive": true,
"shallowReadonly": true,
"shallowRef": true,
"toRaw": true,
"toRef": true,
"toRefs": true,
"toValue": true,
"triggerRef": true,
"unref": true,
"useAttrs": true,
"useCssModule": true,
"useCssVars": true,
"useLink": true,
"useRoute": true,
"useRouter": true,
"useSlots": true,
"watch": true,
"watchEffect": true,
"watchPostEffect": true,
"watchSyncEffect": true,
"asyncComputed": true,
"autoResetRef": true,
"computedAsync": true,
"computedEager": true,
"computedInject": true,
"computedWithControl": true,
"controlledComputed": true,
"controlledRef": true,
"createEventHook": true,
"createGlobalState": true,
"createInjectionState": true,
"createReactiveFn": true,
"createReusableTemplate": true,
"createSharedComposable": true,
"createTemplatePromise": true,
"createUnrefFn": true,
"debouncedRef": true,
"debouncedWatch": true,
"eagerComputed": true,
"extendRef": true,
"ignorableWatch": true,
"injectLocal": true,
"isDefined": true,
"makeDestructurable": true,
"onClickOutside": true,
"onKeyStroke": true,
"onLongPress": true,
"onStartTyping": true,
"pausableWatch": true,
"provideLocal": true,
"reactify": true,
"reactifyObject": true,
"reactiveComputed": true,
"reactiveOmit": true,
"reactivePick": true,
"refAutoReset": true,
"refDebounced": true,
"refDefault": true,
"refThrottled": true,
"refWithControl": true,
"resolveRef": true,
"resolveUnref": true,
"syncRef": true,
"syncRefs": true,
"templateRef": true,
"throttledRef": true,
"throttledWatch": true,
"toReactive": true,
"tryOnBeforeMount": true,
"tryOnBeforeUnmount": true,
"tryOnMounted": true,
"tryOnScopeDispose": true,
"tryOnUnmounted": true,
"unrefElement": true,
"until": true,
"useActiveElement": true,
"useAnimate": true,
"useArrayDifference": true,
"useArrayEvery": true,
"useArrayFilter": true,
"useArrayFind": true,
"useArrayFindIndex": true,
"useArrayFindLast": true,
"useArrayIncludes": true,
"useArrayJoin": true,
"useArrayMap": true,
"useArrayReduce": true,
"useArraySome": true,
"useArrayUnique": true,
"useAsyncQueue": true,
"useAsyncState": true,
"useBase64": true,
"useBattery": true,
"useBluetooth": true,
"useBreakpoints": true,
"useBroadcastChannel": true,
"useBrowserLocation": true,
"useCached": true,
"useClipboard": true,
"useClipboardItems": true,
"useCloned": true,
"useColorMode": true,
"useConfirmDialog": true,
"useCounter": true,
"useCssVar": true,
"useCurrentElement": true,
"useCycleList": true,
"useDark": true,
"useDateFormat": true,
"useDebounce": true,
"useDebounceFn": true,
"useDebouncedRefHistory": true,
"useDeviceMotion": true,
"useDeviceOrientation": true,
"useDevicePixelRatio": true,
"useDevicesList": true,
"useDisplayMedia": true,
"useDocumentVisibility": true,
"useDraggable": true,
"useDropZone": true,
"useElementBounding": true,
"useElementByPoint": true,
"useElementHover": true,
"useElementSize": true,
"useElementVisibility": true,
"useEventBus": true,
"useEventListener": true,
"useEventSource": true,
"useEyeDropper": true,
"useFavicon": true,
"useFetch": true,
"useFileDialog": true,
"useFileSystemAccess": true,
"useFocus": true,
"useFocusWithin": true,
"useFps": true,
"useFullscreen": true,
"useGamepad": true,
"useGeolocation": true,
"useIdle": true,
"useImage": true,
"useInfiniteScroll": true,
"useIntersectionObserver": true,
"useInterval": true,
"useIntervalFn": true,
"useKeyModifier": true,
"useLastChanged": true,
"useLocalStorage": true,
"useMagicKeys": true,
"useManualRefHistory": true,
"useMediaControls": true,
"useMediaQuery": true,
"useMemoize": true,
"useMemory": true,
"useMounted": true,
"useMouse": true,
"useMouseInElement": true,
"useMousePressed": true,
"useMutationObserver": true,
"useNavigatorLanguage": true,
"useNetwork": true,
"useNow": true,
"useObjectUrl": true,
"useOffsetPagination": true,
"useOnline": true,
"usePageLeave": true,
"useParallax": true,
"useParentElement": true,
"usePerformanceObserver": true,
"usePermission": true,
"usePointer": true,
"usePointerLock": true,
"usePointerSwipe": true,
"usePreferredColorScheme": true,
"usePreferredContrast": true,
"usePreferredDark": true,
"usePreferredLanguages": true,
"usePreferredReducedMotion": true,
"usePrevious": true,
"useRafFn": true,
"useRefHistory": true,
"useResizeObserver": true,
"useScreenOrientation": true,
"useScreenSafeArea": true,
"useScriptTag": true,
"useScroll": true,
"useScrollLock": true,
"useSessionStorage": true,
"useShare": true,
"useSorted": true,
"useSpeechRecognition": true,
"useSpeechSynthesis": true,
"useStepper": true,
"useStorage": true,
"useStorageAsync": true,
"useStyleTag": true,
"useSupported": true,
"useSwipe": true,
"useTemplateRefsList": true,
"useTextDirection": true,
"useTextSelection": true,
"useTextareaAutosize": true,
"useThrottle": true,
"useThrottleFn": true,
"useThrottledRefHistory": true,
"useTimeAgo": true,
"useTimeout": true,
"useTimeoutFn": true,
"useTimeoutPoll": true,
"useTimestamp": true,
"useTitle": true,
"useToNumber": true,
"useToString": true,
"useToggle": true,
"useTransition": true,
"useUrlSearchParams": true,
"useUserMedia": true,
"useVModel": true,
"useVModels": true,
"useVibrate": true,
"useVirtualList": true,
"useWakeLock": true,
"useWebNotification": true,
"useWebSocket": true,
"useWebWorker": true,
"useWebWorkerFn": true,
"useWindowFocus": true,
"useWindowScroll": true,
"useWindowSize": true,
"watchArray": true,
"watchAtMost": true,
"watchDebounced": true,
"watchDeep": true,
"watchIgnorable": true,
"watchImmediate": true,
"watchOnce": true,
"watchPausable": true,
"watchThrottled": true,
"watchTriggerable": true,
"watchWithFilter": true,
"whenever": true,
"onWatcherCleanup": true,
"useId": true,
"useModel": true,
"useTemplateRef": true
}
}

View File

@ -0,0 +1,40 @@
name: Release
run-name: ${{ gitea.actor }} is deploying project to test server 🚀
on:
push:
branches:
- develop
jobs:
lint:
on: [push, pull_request]
runs-on: linux_amd64
steps:
- name: 拉取代码
uses: actions/checkout@v4
- name: 安装依赖
run: pnpm i
- name: 执行Lint检查
run: pnpm lint:eslint
Release:
runs-on: linux_amd64
needs:
- lint
steps:
- name: 拉取代码
uses: actions/checkout@v3
- name: 安装依赖
run: pnpm i
- name: 执行打包
run: pnpm build
- name: 部署到服务器
uses: actions/ssh-deploy@main
with:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
ARGS: "-rlgoDzvc -i"
SOURCE: dist/
REMOTE_HOST: ${{ vars.NGINX_SERVER }}
REMOTE_USER: ${{ vars.NGINX_SERVER_USER }}
TARGET: ${{ vars.WWW_ROOT }}${{ vars.DOMAIN }}
EXCLUDE: ""
SCRIPT_BEFORE: ${{ vars.BAKUP_SCRIPT }} ${{ vars.DOMAIN }}
SCRIPT_AFTER: echo $RSYNC_STDOUT

26
.gitignore vendored Normal file
View File

@ -0,0 +1,26 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.mocks/

1
.husky/commit-msg Normal file
View File

@ -0,0 +1 @@
npx --no -- commitlint --edit

1
.husky/pre-commit Normal file
View File

@ -0,0 +1 @@
pnpm run lint:lint-staged

6
.stylelintignore Normal file
View File

@ -0,0 +1,6 @@
dist
node_modules
public
report.html
.husky
.vscode

31
.stylelintrc.js Normal file
View File

@ -0,0 +1,31 @@
export default {
// 继承推荐规范配置
extends: [
'stylelint-config-standard',
'stylelint-config-recommended-scss',
'stylelint-config-recommended-vue/scss',
'stylelint-config-html/vue',
'stylelint-config-recess-order',
],
// 指定不同文件对应的解析器
overrides: [
{
files: ['**/*.{vue,html}'],
customSyntax: 'postcss-html',
},
{
files: ['**/*.{css,scss}'],
customSyntax: 'postcss-scss',
},
],
// 自定义规则
rules: {
// 允许 global 、export 、v-deep等伪类
'selector-pseudo-class-no-unknown': [
true,
{
ignorePseudoClasses: ['global', 'export', 'v-deep', 'deep'],
},
],
},
}

3
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"recommendations": ["Vue.volar"]
}

View File

@ -63,6 +63,7 @@
"eslint-plugin-vue": "^9.28.0",
"globals": "^15.11.0",
"husky": "^9.1.6",
"less": "^4.2.1",
"lint-staged": "^15.2.10",
"pont-engine": "^1.6.3",
"prettier": "^3.3.3",

185
pnpm-lock.yaml generated
View File

@ -116,10 +116,10 @@ importers:
version: 1.15.8
'@vitejs/plugin-vue':
specifier: ^5.1.4
version: 5.1.4(vite@5.4.8(@types/node@22.5.3))(vue@3.5.11(typescript@5.6.3))
version: 5.1.4(vite@5.4.8(@types/node@22.5.3)(less@4.2.1))(vue@3.5.11(typescript@5.6.3))
'@vitejs/plugin-vue-jsx':
specifier: ^4.0.1
version: 4.0.1(vite@5.4.8(@types/node@22.5.3))(vue@3.5.11(typescript@5.6.3))
version: 4.0.1(vite@5.4.8(@types/node@22.5.3)(less@4.2.1))(vue@3.5.11(typescript@5.6.3))
commitizen:
specifier: ^4.3.1
version: 4.3.1(@types/node@22.5.3)(typescript@5.6.3)
@ -144,6 +144,9 @@ importers:
husky:
specifier: ^9.1.6
version: 9.1.6
less:
specifier: ^4.2.1
version: 4.2.1
lint-staged:
specifier: ^15.2.10
version: 15.2.10
@ -191,16 +194,16 @@ importers:
version: 0.27.4(@babel/parser@7.25.6)(@nuxt/kit@3.13.2(rollup@4.21.2)(webpack-sources@3.2.3))(rollup@4.21.2)(vue@3.5.11(typescript@5.6.3))
vite:
specifier: ^5.4.8
version: 5.4.8(@types/node@22.5.3)
version: 5.4.8(@types/node@22.5.3)(less@4.2.1)
vite-eslint-plugin:
specifier: ^1.9.2
version: 1.9.2(@types/eslint@8.56.12)(eslint@9.12.0(jiti@1.21.6))(rollup@4.21.2)(vite@5.4.8(@types/node@22.5.3))
version: 1.9.2(@types/eslint@8.56.12)(eslint@9.12.0(jiti@1.21.6))(rollup@4.21.2)(vite@5.4.8(@types/node@22.5.3)(less@4.2.1))
vite-plugin-compression:
specifier: ^0.5.1
version: 0.5.1(vite@5.4.8(@types/node@22.5.3))
version: 0.5.1(vite@5.4.8(@types/node@22.5.3)(less@4.2.1))
vite-plugin-vue-devtools:
specifier: ^7.4.6
version: 7.4.6(@nuxt/kit@3.13.2(rollup@4.21.2)(webpack-sources@3.2.3))(rollup@4.21.2)(vite@5.4.8(@types/node@22.5.3))(vue@3.5.11(typescript@5.6.3))
version: 7.4.6(@nuxt/kit@3.13.2(rollup@4.21.2)(webpack-sources@3.2.3))(rollup@4.21.2)(vite@5.4.8(@types/node@22.5.3)(less@4.2.1))(vue@3.5.11(typescript@5.6.3))
vue-tsc:
specifier: ^2.1.6
version: 2.1.6(typescript@5.6.3)
@ -1564,6 +1567,9 @@ packages:
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
copy-anything@2.0.6:
resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==}
copy-anything@3.0.5:
resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==}
engines: {node: '>=12.13'}
@ -1778,6 +1784,10 @@ packages:
resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==}
engines: {node: '>=18'}
errno@0.1.8:
resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
hasBin: true
error-ex@1.3.2:
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
@ -2199,6 +2209,10 @@ packages:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
iconv-lite@0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
@ -2206,6 +2220,11 @@ packages:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
engines: {node: '>= 4'}
image-size@0.5.5:
resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==}
engines: {node: '>=0.10.0'}
hasBin: true
immediate@3.0.6:
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
@ -2322,6 +2341,9 @@ packages:
is-utf8@0.2.1:
resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==}
is-what@3.14.1:
resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==}
is-what@4.1.16:
resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
engines: {node: '>=12.13'}
@ -2436,6 +2458,11 @@ packages:
resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==}
engines: {node: '>= 0.6.3'}
less@4.2.1:
resolution: {integrity: sha512-CasaJidTIhWmjcqv0Uj5vccMI7pJgfD9lMkKtlnTHAdJdYK/7l8pM9tumLyJ0zhbD4KJLo/YvTj+xznQd5NBhg==}
engines: {node: '>=6'}
hasBin: true
levn@0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
@ -2568,6 +2595,10 @@ packages:
magic-string@0.30.11:
resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==}
make-dir@2.1.0:
resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==}
engines: {node: '>=6'}
mathml-tag-names@2.1.3:
resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==}
@ -2604,6 +2635,11 @@ packages:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
mime@1.6.0:
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
engines: {node: '>=4'}
hasBin: true
mimic-fn@2.1.0:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
@ -2688,6 +2724,11 @@ packages:
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
needle@3.3.1:
resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==}
engines: {node: '>= 4.4.x'}
hasBin: true
node-fetch-native@1.6.4:
resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==}
@ -2787,6 +2828,10 @@ packages:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'}
parse-node-version@1.0.1:
resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==}
engines: {node: '>= 0.10'}
parse-passwd@1.0.0:
resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==}
engines: {node: '>=0.10.0'}
@ -2843,6 +2888,10 @@ packages:
engines: {node: '>=0.10'}
hasBin: true
pify@4.0.1:
resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
engines: {node: '>=6'}
pinia-plugin-persistedstate@4.1.1:
resolution: {integrity: sha512-fUiUsbfBetGUZzX28z+ImAZw7FDXzwRrk+fN+ljF5OhQMhsSYfYeUzI9FLLtpjekYbfFHWvJiECkLI60RIuiPA==}
peerDependencies:
@ -2945,6 +2994,9 @@ packages:
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
prr@1.0.1:
resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
psl@1.9.0:
resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==}
@ -3078,6 +3130,9 @@ packages:
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
sax@1.4.1:
resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
saxes@5.0.1:
resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==}
engines: {node: '>=10'}
@ -3088,6 +3143,10 @@ packages:
scule@1.3.0:
resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
semver@5.7.2:
resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
hasBin: true
semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
@ -3156,6 +3215,10 @@ packages:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
source-map@0.7.4:
resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
engines: {node: '>= 8'}
@ -4798,19 +4861,19 @@ snapshots:
transitivePeerDependencies:
- encoding
'@vitejs/plugin-vue-jsx@4.0.1(vite@5.4.8(@types/node@22.5.3))(vue@3.5.11(typescript@5.6.3))':
'@vitejs/plugin-vue-jsx@4.0.1(vite@5.4.8(@types/node@22.5.3)(less@4.2.1))(vue@3.5.11(typescript@5.6.3))':
dependencies:
'@babel/core': 7.25.2
'@babel/plugin-transform-typescript': 7.25.2(@babel/core@7.25.2)
'@vue/babel-plugin-jsx': 1.2.2(@babel/core@7.25.2)
vite: 5.4.8(@types/node@22.5.3)
vite: 5.4.8(@types/node@22.5.3)(less@4.2.1)
vue: 3.5.11(typescript@5.6.3)
transitivePeerDependencies:
- supports-color
'@vitejs/plugin-vue@5.1.4(vite@5.4.8(@types/node@22.5.3))(vue@3.5.11(typescript@5.6.3))':
'@vitejs/plugin-vue@5.1.4(vite@5.4.8(@types/node@22.5.3)(less@4.2.1))(vue@3.5.11(typescript@5.6.3))':
dependencies:
vite: 5.4.8(@types/node@22.5.3)
vite: 5.4.8(@types/node@22.5.3)(less@4.2.1)
vue: 3.5.11(typescript@5.6.3)
'@volar/language-core@2.4.1':
@ -4947,14 +5010,14 @@ snapshots:
'@vue/devtools-api@6.6.4': {}
'@vue/devtools-core@7.4.6(vite@5.4.8(@types/node@22.5.3))(vue@3.5.11(typescript@5.6.3))':
'@vue/devtools-core@7.4.6(vite@5.4.8(@types/node@22.5.3)(less@4.2.1))(vue@3.5.11(typescript@5.6.3))':
dependencies:
'@vue/devtools-kit': 7.4.6
'@vue/devtools-shared': 7.4.6
mitt: 3.0.1
nanoid: 3.3.7
pathe: 1.1.2
vite-hot-client: 0.2.3(vite@5.4.8(@types/node@22.5.3))
vite-hot-client: 0.2.3(vite@5.4.8(@types/node@22.5.3)(less@4.2.1))
vue: 3.5.11(typescript@5.6.3)
transitivePeerDependencies:
- vite
@ -5486,6 +5549,10 @@ snapshots:
convert-source-map@2.0.0: {}
copy-anything@2.0.6:
dependencies:
is-what: 3.14.1
copy-anything@3.0.5:
dependencies:
is-what: 4.1.16
@ -5667,6 +5734,11 @@ snapshots:
environment@1.1.0: {}
errno@0.1.8:
dependencies:
prr: 1.0.1
optional: true
error-ex@1.3.2:
dependencies:
is-arrayish: 0.2.1
@ -6164,10 +6236,18 @@ snapshots:
dependencies:
safer-buffer: 2.1.2
iconv-lite@0.6.3:
dependencies:
safer-buffer: 2.1.2
optional: true
ieee754@1.2.1: {}
ignore@5.3.2: {}
image-size@0.5.5:
optional: true
immediate@3.0.6: {}
import-fresh@3.3.0:
@ -6274,6 +6354,8 @@ snapshots:
is-utf8@0.2.1: {}
is-what@3.14.1: {}
is-what@4.1.16: {}
is-windows@1.0.2: {}
@ -6366,6 +6448,20 @@ snapshots:
dependencies:
readable-stream: 2.3.8
less@4.2.1:
dependencies:
copy-anything: 2.0.6
parse-node-version: 1.0.1
tslib: 2.7.0
optionalDependencies:
errno: 0.1.8
graceful-fs: 4.2.11
image-size: 0.5.5
make-dir: 2.1.0
mime: 1.6.0
needle: 3.3.1
source-map: 0.6.1
levn@0.4.1:
dependencies:
prelude-ls: 1.2.1
@ -6493,6 +6589,12 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0
make-dir@2.1.0:
dependencies:
pify: 4.0.1
semver: 5.7.2
optional: true
mathml-tag-names@2.1.3: {}
mdn-data@2.0.30: {}
@ -6518,6 +6620,9 @@ snapshots:
dependencies:
mime-db: 1.52.0
mime@1.6.0:
optional: true
mimic-fn@2.1.0: {}
mimic-fn@4.0.0: {}
@ -6582,6 +6687,12 @@ snapshots:
natural-compare@1.4.0: {}
needle@3.3.1:
dependencies:
iconv-lite: 0.6.3
sax: 1.4.1
optional: true
node-fetch-native@1.6.4: {}
node-fetch@2.7.0:
@ -6694,6 +6805,8 @@ snapshots:
json-parse-even-better-errors: 2.3.1
lines-and-columns: 1.2.4
parse-node-version@1.0.1: {}
parse-passwd@1.0.0: {}
path-browserify@1.0.1: {}
@ -6724,6 +6837,9 @@ snapshots:
pidtree@0.6.0: {}
pify@4.0.1:
optional: true
pinia-plugin-persistedstate@4.1.1(pinia@2.2.4(typescript@5.6.3)(vue@3.5.11(typescript@5.6.3)))(rollup@4.21.2)(webpack-sources@3.2.3):
dependencies:
'@nuxt/kit': 3.13.2(rollup@4.21.2)(webpack-sources@3.2.3)
@ -6830,6 +6946,9 @@ snapshots:
proxy-from-env@1.1.0: {}
prr@1.0.1:
optional: true
psl@1.9.0: {}
punycode@2.3.1: {}
@ -6987,6 +7106,9 @@ snapshots:
safer-buffer@2.1.2: {}
sax@1.4.1:
optional: true
saxes@5.0.1:
dependencies:
xmlchars: 2.2.0
@ -6997,6 +7119,9 @@ snapshots:
scule@1.3.0: {}
semver@5.7.2:
optional: true
semver@6.3.1: {}
semver@7.6.3: {}
@ -7049,6 +7174,9 @@ snapshots:
source-map-js@1.2.1: {}
source-map@0.6.1:
optional: true
source-map@0.7.4: {}
speakingurl@14.0.1: {}
@ -7488,29 +7616,29 @@ snapshots:
core-util-is: 1.0.2
extsprintf: 1.3.0
vite-eslint-plugin@1.9.2(@types/eslint@8.56.12)(eslint@9.12.0(jiti@1.21.6))(rollup@4.21.2)(vite@5.4.8(@types/node@22.5.3)):
vite-eslint-plugin@1.9.2(@types/eslint@8.56.12)(eslint@9.12.0(jiti@1.21.6))(rollup@4.21.2)(vite@5.4.8(@types/node@22.5.3)(less@4.2.1)):
dependencies:
'@rollup/pluginutils': 5.1.0(rollup@4.21.2)
'@types/eslint': 8.56.12
eslint: 9.12.0(jiti@1.21.6)
vite: 5.4.8(@types/node@22.5.3)
vite: 5.4.8(@types/node@22.5.3)(less@4.2.1)
transitivePeerDependencies:
- rollup
vite-hot-client@0.2.3(vite@5.4.8(@types/node@22.5.3)):
vite-hot-client@0.2.3(vite@5.4.8(@types/node@22.5.3)(less@4.2.1)):
dependencies:
vite: 5.4.8(@types/node@22.5.3)
vite: 5.4.8(@types/node@22.5.3)(less@4.2.1)
vite-plugin-compression@0.5.1(vite@5.4.8(@types/node@22.5.3)):
vite-plugin-compression@0.5.1(vite@5.4.8(@types/node@22.5.3)(less@4.2.1)):
dependencies:
chalk: 4.1.2
debug: 4.3.6
fs-extra: 10.1.0
vite: 5.4.8(@types/node@22.5.3)
vite: 5.4.8(@types/node@22.5.3)(less@4.2.1)
transitivePeerDependencies:
- supports-color
vite-plugin-inspect@0.8.7(@nuxt/kit@3.13.2(rollup@4.21.2)(webpack-sources@3.2.3))(rollup@4.21.2)(vite@5.4.8(@types/node@22.5.3)):
vite-plugin-inspect@0.8.7(@nuxt/kit@3.13.2(rollup@4.21.2)(webpack-sources@3.2.3))(rollup@4.21.2)(vite@5.4.8(@types/node@22.5.3)(less@4.2.1)):
dependencies:
'@antfu/utils': 0.7.10
'@rollup/pluginutils': 5.1.0(rollup@4.21.2)
@ -7521,30 +7649,30 @@ snapshots:
perfect-debounce: 1.0.0
picocolors: 1.1.0
sirv: 2.0.4
vite: 5.4.8(@types/node@22.5.3)
vite: 5.4.8(@types/node@22.5.3)(less@4.2.1)
optionalDependencies:
'@nuxt/kit': 3.13.2(rollup@4.21.2)(webpack-sources@3.2.3)
transitivePeerDependencies:
- rollup
- supports-color
vite-plugin-vue-devtools@7.4.6(@nuxt/kit@3.13.2(rollup@4.21.2)(webpack-sources@3.2.3))(rollup@4.21.2)(vite@5.4.8(@types/node@22.5.3))(vue@3.5.11(typescript@5.6.3)):
vite-plugin-vue-devtools@7.4.6(@nuxt/kit@3.13.2(rollup@4.21.2)(webpack-sources@3.2.3))(rollup@4.21.2)(vite@5.4.8(@types/node@22.5.3)(less@4.2.1))(vue@3.5.11(typescript@5.6.3)):
dependencies:
'@vue/devtools-core': 7.4.6(vite@5.4.8(@types/node@22.5.3))(vue@3.5.11(typescript@5.6.3))
'@vue/devtools-core': 7.4.6(vite@5.4.8(@types/node@22.5.3)(less@4.2.1))(vue@3.5.11(typescript@5.6.3))
'@vue/devtools-kit': 7.4.6
'@vue/devtools-shared': 7.4.6
execa: 8.0.1
sirv: 2.0.4
vite: 5.4.8(@types/node@22.5.3)
vite-plugin-inspect: 0.8.7(@nuxt/kit@3.13.2(rollup@4.21.2)(webpack-sources@3.2.3))(rollup@4.21.2)(vite@5.4.8(@types/node@22.5.3))
vite-plugin-vue-inspector: 5.2.0(vite@5.4.8(@types/node@22.5.3))
vite: 5.4.8(@types/node@22.5.3)(less@4.2.1)
vite-plugin-inspect: 0.8.7(@nuxt/kit@3.13.2(rollup@4.21.2)(webpack-sources@3.2.3))(rollup@4.21.2)(vite@5.4.8(@types/node@22.5.3)(less@4.2.1))
vite-plugin-vue-inspector: 5.2.0(vite@5.4.8(@types/node@22.5.3)(less@4.2.1))
transitivePeerDependencies:
- '@nuxt/kit'
- rollup
- supports-color
- vue
vite-plugin-vue-inspector@5.2.0(vite@5.4.8(@types/node@22.5.3)):
vite-plugin-vue-inspector@5.2.0(vite@5.4.8(@types/node@22.5.3)(less@4.2.1)):
dependencies:
'@babel/core': 7.25.2
'@babel/plugin-proposal-decorators': 7.24.7(@babel/core@7.25.2)
@ -7555,11 +7683,11 @@ snapshots:
'@vue/compiler-dom': 3.5.7
kolorist: 1.8.0
magic-string: 0.30.11
vite: 5.4.8(@types/node@22.5.3)
vite: 5.4.8(@types/node@22.5.3)(less@4.2.1)
transitivePeerDependencies:
- supports-color
vite@5.4.8(@types/node@22.5.3):
vite@5.4.8(@types/node@22.5.3)(less@4.2.1):
dependencies:
esbuild: 0.21.5
postcss: 8.4.47
@ -7567,6 +7695,7 @@ snapshots:
optionalDependencies:
'@types/node': 22.5.3
fsevents: 2.3.3
less: 4.2.1
vscode-uri@3.0.8: {}

View File

@ -3704,6 +3704,120 @@
]
}
]
},
{
"description": "盘点管理",
"name": "stocktaking",
"interfaces": [
{
"description": "增加/编辑盘点",
"name": "saveOrUpdateStocktaking",
"method": "put",
"path": "/stocktaking",
"response": {
"typeArgs": [],
"typeName": "Stocktaking",
"isDefsType": true,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"parameters": [
{
"required": true,
"in": "body",
"name": "requestBody",
"dataType": {
"typeArgs": [],
"typeName": "Stocktaking",
"isDefsType": true,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
}
}
]
},
{
"description": "分页查询盘点列表",
"name": "stocktakingList",
"method": "get",
"path": "/stocktaking-list",
"response": {
"typeArgs": [],
"typeName": "IPageStocktaking",
"isDefsType": true,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"parameters": [
{
"description": "页码",
"required": false,
"in": "query",
"name": "page",
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
}
},
{
"description": "页面大小",
"required": false,
"in": "query",
"name": "size",
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
}
},
{
"description": "类型",
"required": false,
"in": "query",
"name": "type",
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
}
},
{
"description": "搜索关键词",
"required": false,
"in": "query",
"name": "key",
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
}
}
]
}
]
}
],
"name": "material",
@ -4180,6 +4294,87 @@
}
]
},
{
"name": "IPageStocktaking",
"templateArgs": [],
"properties": [
{
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "current",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "pages",
"required": false
},
{
"dataType": {
"typeArgs": [
{
"typeArgs": [],
"typeName": "Stocktaking",
"isDefsType": true,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
}
],
"typeName": "Array",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "records",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "size",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "total",
"required": false
}
]
},
{
"description": "物料信息",
"name": "Material",
@ -4323,6 +4518,178 @@
"required": false
}
]
},
{
"description": "盘点信息",
"name": "Stocktaking",
"templateArgs": [],
"properties": [
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "createdTime",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "date",
"description": "盘点日期",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "exception",
"description": "异常原因",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "exceptionHandle",
"description": "异常情况处理方式",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "id",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "operator",
"description": "盘点人",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "result",
"description": "盘点结果(系统自动生成)",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "reviewResult",
"description": "盘点审核结果",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "reviewer",
"description": "盘点审核人",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "status",
"description": "盘点任务状态",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "number",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "type",
"description": "盘点类型",
"required": false
},
{
"dataType": {
"typeArgs": [],
"typeName": "string",
"isDefsType": false,
"templateIndex": -1,
"compileTemplateKeyword": "#/definitions/",
"enum": [],
"typeProperties": []
},
"name": "updatedTime",
"required": false
}
]
}
]
}

View File

@ -102,4 +102,45 @@ declare namespace material {
/** updatedTime */
updatedTime?: string;
}
/**
*
*/
export interface Stocktaking {
/** createdTime */
createdTime?: string;
/** 盘点日期 */
date?: string;
/** 异常原因 */
exception?: string;
/** 异常情况处理方式 */
exceptionHandle?: string;
/** id */
id?: number;
/** 盘点人 */
operator?: string;
/** 盘点结果(系统自动生成) */
result?: string;
/** 盘点审核结果 */
reviewResult?: string;
/** 盘点审核人 */
reviewer?: string;
/** 盘点任务状态 */
status?: number;
/** 盘点类型 */
type?: number;
/** updatedTime */
updatedTime?: string;
}
}

View File

@ -2,7 +2,10 @@ import apply from './apply';
import material from './material';
import stocktaking from './stocktaking';
export default {
apply,
material,
stocktaking,
};

View File

@ -0,0 +1,11 @@
/**
* @description
*
*/
import saveOrUpdateStocktaking from './saveOrUpdateStocktaking';
import stocktakingList from './stocktakingList';
export default {
saveOrUpdateStocktaking,
stocktakingList,
};

View File

@ -0,0 +1,33 @@
/**
* @desc
*/
import { defaultSuccess, defaultError, http } from '@/plugins/axios';
import type { AxiosResponse } from 'axios';
import type { IPage } from '@/api/api';
export interface Params {
/** 页码 */
page?: number;
/** 页面大小 */
size?: number;
/** 类型 */
type?: number;
/** 搜索关键词 */
key?: string;
}
export default async function (
params: Params,
success: (data: IPage<material.Stocktaking>) => void = defaultSuccess,
fail: (error: { code: string; error?: string }) => void = defaultError,
): Promise<void> {
return http({
method: 'get',
url: `/stocktaking-list`,
params,
})
.then((data: AxiosResponse<IPage<material.Stocktaking>, unknown>) => {
success(data.data);
})
.catch((error: { code: string; error?: string }) => fail(error));
}

View File

@ -0,0 +1,22 @@
/**
* @desc /
*/
import { defaultSuccess, defaultError, http } from '@/plugins/axios';
import type { AxiosResponse } from 'axios';
export default async function (
/** 请求体 */
requestBody: material.Stocktaking,
success: (data: material.Stocktaking) => void = defaultSuccess,
fail: (error: { code: string; error?: string }) => void = defaultError,
): Promise<void> {
return http({
method: 'put',
url: `/stocktaking`,
data: requestBody,
})
.then((data: AxiosResponse<material.Stocktaking, unknown>) => {
success(data.data);
})
.catch((error: { code: string; error?: string }) => fail(error));
}

View File

@ -0,0 +1,33 @@
/**
* @desc
*/
import { defaultSuccess, defaultError, http } from '@/plugins/axios';
import type { AxiosResponse } from 'axios';
import type { IPage } from '@/api/api';
export interface Params {
/** 页码 */
page?: number;
/** 页面大小 */
size?: number;
/** 类型 */
type?: number;
/** 搜索关键词 */
key?: string;
}
export default async function (
params: Params,
success: (data: IPage<material.Stocktaking>) => void = defaultSuccess,
fail: (error: { code: string; error?: string }) => void = defaultError,
): Promise<void> {
return http({
method: 'get',
url: `/stocktaking-list`,
params,
})
.then((data: AxiosResponse<IPage<material.Stocktaking>, unknown>) => {
success(data.data);
})
.catch((error: { code: string; error?: string }) => fail(error));
}

View File

@ -1,17 +1,5 @@
{
"index": "首页",
"dashboard": "仪表盘",
"dictionary": "数据字典",
"sensor": "传感器管理",
"factory": {
"name": "班组&工位",
"team": "班组管理",
"detail": "工位详情",
"station": "焊接工位"
},
"acl": {
"name": "系统管理",
"users": "用户管理",
@ -24,12 +12,12 @@
"stock": "库存查询",
"inbound": "入库查询",
"outbound": "出库查询",
"inventory": "盘点查询"
"stocktaking": "盘点查询"
},
"stock": {
"name": "库存管理",
"inbound": "入库管理",
"outbound": "出库管理",
"inventory": "盘点管理"
"stocktaking": "盘点管理"
}
}

View File

@ -47,20 +47,20 @@ export const routes = [
{
path: '/stock/inbound', //入库
name: 'Inbound',
meta: {title: '入库申请',icon: 'icon-permission'},
component: ()=> import('../../src/views/stock/inboud/inboud-page.vue'), // 好奇怪,新创建的文件,要多向上找一层才不会报错
meta: {title: 'menus.stock.inbound',icon: 'icon-permission'},
component: ()=> import('../views/stock/inboud/inboud-page.vue'),
},
{
path: '/stock/outbound', //出库
name: 'Outbound',
meta: {title: '出库申请',icon: 'icon-permission'},
component: ()=> import('../views/admin/sensor/sensor-page.vue'),
meta: {title: 'menus.stock.outbound',icon: 'icon-permission'},
component: ()=> import('../views/stock/outboud/outbound-page.vue'),
},
{
path: '/stock/inventory', //盘点
name: 'Inventory',
meta: {title: '盘点申请',icon: 'icon-permission'},
component: ()=> import('../views/admin/sensor/sensor-page.vue')
path: '/stock/stocktaking', //盘点
name: 'Stocktaking',
meta: {title: 'menus.stock.stocktaking',icon: 'icon-permission'},
component: ()=> import('../views/stock/stocktaking/stocktaking-page.vue')
},
]
},
@ -71,23 +71,29 @@ export const routes = [
component: BlankLayout,
redirect: () => ({ name: 'S-Inbound' }),
children: [
{
path: '/statistic/stock', //库存
name: 'S-stock',
meta: {title: 'menus.statistic.stock',icon: 'icon-permission'},
component: ()=> import('../views/stock/report/materialReport-page.vue'),
},
{
path: '/statistic/inbound', //入库
name: 'S-Inbound',
meta: {title: 'menus.statistic.inbound',icon: 'icon-permission'},
component: ()=> import('../views/admin/sensor/sensor-page.vue'),
component: ()=> import('../views/stock/report/inboundReport-page.vue'),
},
{
path: '/statistic/outbound', //出库
name: 'S-Outbound',
meta: {title: 'menus.statistic.outbound',icon: 'icon-permission'},
component: ()=> import('../views/admin/sensor/sensor-page.vue'),
component: ()=> import('../views/stock/report/outboundReport-page.vue'),
},
{
path: '/statistic/inventory', //盘点
name: 'S-Inventory',
meta: {title: 'menus.statistic.inventory',icon: 'icon-permission'},
component: ()=> import('../views/admin/sensor/sensor-page.vue'),
path: '/statistic/stocktaking', //盘点
name: 'S-stocktaking',
meta: {title: 'menus.statistic.stocktaking',icon: 'icon-permission'},
component: ()=> import('../views/stock/report/stocktakingReport-page.vue'),
},
]
}

View File

@ -0,0 +1,146 @@
<template>
<page-container>
<!-- 页面操作栏 -->
<template #ops>
<a-row>
<a-col :span="18">
<a-input-search v-model:value="searchKey" :placeholder="`请输入`" allow-clear enter-button
@search="loadData()"></a-input-search>
</a-col>
<a-col :span="6">
<a-button type="primary" style="margin-left: 10px" @click="showModal">
<template #icon>
<icon-font type="icon-plus" />
</template>
{{ pageType === '1'? '申请入库' : '申请出库' }}
</a-button>
</a-col>
</a-row>
</template>
<!-- 页面表格内容 -->
<div style="min-height: calc(100vh - 305px)">
<!-- 表格行 -->
<a-table :columns="columns" :data-source="pagedata?.records" bordered :pagination="pagination"
:loading="loading" row-key="key">
</a-table>
</div>
</page-container>
<!-- 弹窗 -->
<a-modal v-model:open="open" title="Basic Modal" width="100%" wrap-class-name="full-modal" @ok="handleOk">
<apply></apply>
</a-modal>
</template>
<script setup lang="ts">
import api from '@/api'
import { IPage } from '@/api/api'
import apply from './applyModal.vue';
const props = defineProps({
pageType: {
type: String as PropType<'1' | '2' >, // 1 2
required: false,
default: '1'
}
})
const { pageType} = toRefs(props)
const searchKey = ref('')
const pagedata = ref<IPage<material.ApplyForm>>()
const loading = ref(false)
//
const loadData = async (page = 1, size = 10) => {
loading.value = true
api.materialApi.apply.applies(
//1: 2: 3:
{ type: 1, page: page || pagedata.value?.current, size: size || pagedata.value?.size, key: searchKey.value },
(data) => {
loading.value = false
pagedata.value = data
},
)
}
//
loadData()
//
const columns = [
{
title: '类型',
dataIndex: 'type',
},
{
title: '申请人',
dataIndex: 'applicant',
},
{
title: '申请日期',
dataIndex: 'applyDate',
},
{
title: '是否确认',
dataIndex: 'isConfirm',
},
{
title: '创建人',
dataIndex: 'createdBy',
},
{
title: '创建时间',
dataIndex: 'createdTime',
}
]
//
const pagination = computed(() => {
return {
current: pagedata.value?.current,
pageSize: pagedata.value?.size,
total: pagedata.value?.total,
onChange: (page: number, pageSize: number) => {
loadData(page, pageSize)
},
}
})
const open = ref<boolean>(false);
const showModal = () => {
open.value = true;
};
const handleOk = (e: MouseEvent) => {
console.log(e);
open.value = false;
};
</script>
<style lang="less">
.full-modal {
.ant-modal {
max-width: 100%;
top: 0;
padding-bottom: 0;
margin: 0;
}
.ant-modal-content {
display: flex;
flex-direction: column;
height: calc(100vh);
}
.ant-modal-body {
flex: 1;
}
}
</style>

View File

@ -0,0 +1,186 @@
<template>
<!-- 基本信息的表单 -->
<div>
<a-form :model="formData" name="basic" layout="horizontal" labelWrap>
<a-form-item label="申请人" name="applicant">
<a-input v-model:value="formData.applicant" style="width: 40%;" />
</a-form-item>
<a-form-item label="申请类型" name="applyType">
<a-radio-group v-model:value="formData.applyType" button-style="solid" style="width: 40%;">
<a-radio-button value=1>采购入库</a-radio-button>
<a-radio-button value=2>归还入库</a-radio-button>
</a-radio-group>
</a-form-item>
<a-form-item label="申请日期" name="applyDate" style="width: 40%;">
<a-date-picker />
</a-form-item>
<a-form-item label="入库物料" name="selected">
<a-select v-model:value="formData.slectedList" mode="multiple" bordered placeholder="请选择入库物料"
style="width: 40%;" showArrow :options="options" @deselect="removeEvent"
@select="insertEvent"></a-select>
</a-form-item>
</a-form>
</div>
<!-- vxe-table -->
<div>
<vxe-table border show-overflow ref="tableRef" max-height="500" :column-config="{ resizable: true }"
size="medium" :data="tableData" empty-text="请先选择入库物料" :edit-config="{ trigger: 'click', mode: 'cell' }"
:checkbox-config="{ trigger: 'row', highlight: true }">
<vxe-column type="seq" title="序号" width="60"></vxe-column>
<vxe-column field="id" title="物料id" :visible="false"></vxe-column>
<vxe-column field="role" title="物料名称" beforeEditMethod="false">
<template #default="{ row }">
<span>{{ row.name }}</span>
</template>
</vxe-column>
<vxe-column field="code" title="编码" beforeEditMethod="false">
<template #edit="{ row }">
<vxe-input v-model="row.code" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="spec" title="规格" beforeEditMethod="false">
<template #edit="{ row }">
<vxe-input v-model="row.spec" type="text" transfer></vxe-input>
</template>
</vxe-column>
<vxe-column field="type" title="类型" beforeEditMethod="false">
<template #edit="{ row }">
<vxe-input v-model="row.type" type="text" transfer>
</vxe-input>
</template>
</vxe-column>
<vxe-column field="assignRule" title="赋码规则" beforeEditMethod="false">
<template #edit="{ row }">
<vxe-input v-model="row.assignRule" type="text" transfer>
</vxe-input>
</template>
</vxe-column>
<vxe-column field="quantity" title="申请数量" :edit-render="{}">
<template #edit="{ row }">
<vxe-number-input v-model="row.quantity" type="integer"></vxe-number-input>
</template>
</vxe-column>
<vxe-column field="oprator" title="操作" beforeEditMethod="false">
<template #default="{ row }">
<vxe-button mode="text" status="error" @click="removeRow(row)">删除</vxe-button>
</template>
</vxe-column>
</vxe-table>
</div>
</template>
<script setup lang="ts">
import { VxeTableInstance } from 'vxe-table'
import api from '@/api'
import { useUserStore } from '@/stores/user'
interface FormData {
applicant: string; //
applyDate: Date; //
applyType: number; //
slectedList: string[]; //
}
const userStore = useUserStore()
const formData = ref<FormData>({
applicant: userStore.userName,
applyDate: new Date(),
applyType: 1, // 1: 2: 3:
slectedList: []
});
// vxe-table
interface RowVO {
id: number
name: string
code: string
spec: string
type: string
quantity: number
disabled: boolean
checked: boolean
assignRule: number
}
const tableRef = ref<VxeTableInstance<RowVO>>()
// vxe-table
const tableData = ref<Array<RowVO>>([])
//
const options = ref<{ label: string, value: number }[]>([])
const materialList = ref<material.Material[]>([])
const getMaterialList = async () => {
await api.materialApi.material.all((data) => {
materialList.value = data
})
options.value = materialList.value.map((item) => {
return { label: item.name ? item.name : '未知', value: item.id ? item.id : -1 }
})
}
getMaterialList()
//
// value: number, option: { label: string, value: number }
const insertEvent = (value: string) => {
window.console.log('insertEvent', tableData.value)
// value
const material = materialList.value.find((item) => item.id === (value ? parseInt(value) : -1))
if (material) {
const row: RowVO = {
id: material.id ? material.id : -1,
name: material.name ? material.name : '未知',
code: material.code ? material.code : '未知',
spec: material.spec ? material.spec : '未知',
type: material.type ? material.type : '未知',
quantity: 1,
assignRule: material.assignRule ? material.assignRule : 1,
disabled: false,
checked: false
}
const $table = tableRef.value
if ($table) {
$table.insertAt(row, -1)
}
}
}
// table
const removeEvent = (value: string) => {
const $table = tableRef.value
// value
if ($table) {
$table.getTableData().fullData.forEach((item) => {
if (item.id === (value ? parseInt(value) : -1)) {
$table.remove(item)
}
})
}
}
// table
const removeRow = async (row: RowVO) => {
//tableData
const $table = tableRef.value
if ($table) {
// row.id
formData.value.slectedList.forEach((item, index) => {
if (item.toString() === row.id.toString()) {
formData.value.slectedList.splice(index, 1)
}
})
$table.remove(row)
}
}
</script>

View File

@ -0,0 +1,50 @@
<template>
<!-- steps -->
<div>
<a-steps v-model:current="current" :items="items"></a-steps>
</div>
<a-divider style="height: 2px; background-color: #7cb305" />
<!-- step1 -->
<div class="step-1" v-if="current === 0">
<!--第一步 -->
<apply-form></apply-form>
</div>
<!-- step2 -->
<div class="step-2" v-if="current === 1">
<scan-form></scan-form>
</div>
<!-- 按钮 -->
<a-space wrap class="fixed-button-container">
<a-button type="default" @click="current = current - 1" v-if="current > 0">上一步</a-button>
<a-button type="primary" @click="current = current + 1" v-if="current < 2">下一步</a-button>
<a-button type="primary" @click="btnClick" v-if="current === 2">提交</a-button>
</a-space>
</template>
<script setup lang="ts">
import applyForm from '../component/applyForm.vue'
import scanForm from '../component/scanForm.vue';
// steps
const current = ref<number>(0)
const items = [{ title: '录入申请' }, { title: '扫码点货' }, { title: '人工确认' }]
const btnClick = () => {
console.log('提交')
}
</script>
<style scoped>
/* 固定按钮容器样式 */
.fixed-button-container {
position: fixed;
bottom: 80px;
/* 距离底部的距离 */
right: 30px;
/* 距离右侧的距离 */
z-index: 1000;
/* 确保按钮在其他内容之上 */
}
</style>

View File

@ -0,0 +1,91 @@
<template>
<a-button type="primary" @click="autoInsertOneRow">开始扫码</a-button>
<a-button type="primary" danger style="left: 20px;">重新扫码</a-button>
<vxe-table border stripe show-overflow ref="applyDetailTableRef" max-height="500"
:column-config="{ resizable: true }" :keyboard-config="{ isEsc: true, isEnter: true }" size="medium"
empty-text="请先扫码物料体条码" :edit-config="{ trigger: 'click', mode: 'cell', autoFocus: true}">
<vxe-column type="seq" title="序号" width="60"></vxe-column>
<vxe-column field="id" title="物料id" :visible="false"></vxe-column>
<vxe-column field="barcode" title="物料条码" :edit-render="{ name: 'input', autoSelect: true }">
<template #edit="{ row }">
<vxe-input v-model="row.barcode" type="text" class="my-input" transfer></vxe-input>
</template>
</vxe-column>
<vxe-column field="role" title="物料名称" beforeEditMethod="false">
<template #default="{ row }">
<span>{{ row.name }}</span>
</template>
</vxe-column>
<vxe-column field="code" title="编码" beforeEditMethod="false">
<template #edit="{ row }">
<vxe-input v-model="row.code" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="spec" title="规格" beforeEditMethod="false">
<template #edit="{ row }">
<vxe-input v-model="row.spec" type="text" transfer></vxe-input>
</template>
</vxe-column>
<vxe-column field="type" title="类型" beforeEditMethod="false">
<template #edit="{ row }">
<vxe-input v-model="row.type" type="text" transfer>
</vxe-input>
</template>
</vxe-column>
<vxe-column field="oprator" title="操作" beforeEditMethod="false">
<template #default="{ row }">
<vxe-button mode="text" status="error" @click="removeStep2Row(row)">删除</vxe-button>
</template>
</vxe-column>
</vxe-table>
</template>
<script lang="ts" setup>
import { VxeTableInstance } from 'vxe-table'
interface Step2RowVO {
barcode: string
name: string
code: string
spec: string
type: string
times: Date
}
// table
const applyDetailTableRef = ref<VxeTableInstance<Step2RowVO>>()
// table
const removeStep2Row = async (row: Step2RowVO) => {
const $table = applyDetailTableRef.value
if ($table) {
$table.remove(row)
}
}
//
const autoInsertOneRow = async () => {
const $table = applyDetailTableRef.value
// //
// const fullData = $table?.getTableData().fullData;
if ($table) {
const row: Step2RowVO = {
barcode: '',
name: '',
code: '',
spec: '',
type: '',
times: new Date()
}
$table.insertAt(row, -1)
}
}
</script>

View File

@ -1,97 +0,0 @@
<template>
<div>
<vxe-toolbar>
<template #buttons>
<vxe-button @click="insertEvent()">添加物料</vxe-button>
</template>
</vxe-toolbar>
<vxe-table
border
show-overflow
ref="tableRef"
isDel
max-height="400"
:column-config="{ resizable: true }"
:data="tableData"
:edit-config="{ trigger: 'click', mode: 'row' }"
@edit-activated="editActivatedEvent"
>
<vxe-column type="seq" width="60"></vxe-column>
<vxe-column field="id" title="物料id" :visible="false"></vxe-column>
<vxe-column field="code" title="物料编码" :edit-render="{}">
<template #edit="{ row }">
<vxe-input v-model="row.code" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="name" title="物料名称" :edit-render="{}">
<template #default="{ row }">
<span>{{ row.name }}</span>
</template>
<template #edit="{ row }">
<vxe-select v-model="row.name" clearable transfer @change="materialChangeEvent(row)">
<vxe-option v-for="item in materialList" :key="item.id" :value="item.name" :label="item.name"></vxe-option>
</vxe-select>
</template>
</vxe-column>
<vxe-column field="quantity" title="数量" :edit-render="{}">
<template #edit="{ row }">
<vxe-input v-model="row.quantity" type="number" transfer></vxe-input>
</template>
</vxe-column>
<vxe-column field="spec" title="型号" :edit-render="{}">
<template #edit="{ row }">
<vxe-input v-model="row.spec" type="text" transfer></vxe-input>
</template>
</vxe-column>
</vxe-table>
</div>
</template>
<script lang="ts" setup>
import api from '@/api'
import { ref } from 'vue'
import { VxeTableInstance } from 'vxe-table'
interface RowVO {
id: number
code: string
name: string
quantity: number
spec: string
}
const tableRef = ref<VxeTableInstance<RowVO>>()
const tableData = ref<RowVO[]>([])
const materialList = ref<material.Material[]>([])
//
const getMaterialList = async () => {
await api.materialApi.material.all((data) => {
materialList.value = data
})
}
getMaterialList()
const insertEvent = () => {
const $table = tableRef.value
if ($table) {
const record = {}
$table.insert(record)
}
}
//
const materialChangeEvent = (row: RowVO) => {
materialList.value.forEach((item) => {
if (item.name === row.name) {
row.code = item.code ? item.code : ''
row.quantity = 1
row.spec = item.spec ? item.spec : ''
}
})
}
</script>

View File

@ -1,110 +0,0 @@
import { FormItem, FormConfig } from '@/components/form-render/form-render-types'
export const config: FormConfig = {
layout: 'horizontal',
colon: true,
hideRequiredMark: false,
labelAlign: 'right',
scrollToFirstError: false,
validateOnRuleChange: true,
labelCol: {
span: 4,
offset: 0,
},
}
export const formItems: FormItem[] = [
{
group: 'form',
type: 'input',
config: {
autoLink: true,
hasFeedback: false,
label: '物料名称',
name: 'name',
required: true,
},
properties: {
size: 'default',
type: 'text',
allowClear: false,
bordered: true,
showCount: false,
placeholder: '请输入物料名称',
},
rules: [],
},
{
group: 'form',
type: 'input',
config: {
autoLink: true,
hasFeedback: false,
label: '物料类型',
name: 'type',
},
properties: {
size: 'default',
type: 'text',
allowClear: false,
bordered: true,
showCount: false,
placeholder: '请输入物料类型',
},
rules: [],
},
{
type: 'input',
group: 'form',
config: {
autoLink: true,
hasFeedback: false,
label: '物料型号',
name: 'spec',
required: true,
},
properties: {
size: 'default',
controls: true,
placeholder: '请填写物料型号',
},
rules: [],
},
{
type: 'select',
group: 'form',
config: {
autoLink: true,
hasFeedback: false,
label: '赋码规则',
name: 'assignRule',
required: true,
},
properties: {
size: 'default',
controls: true,
placeholder: '请填写赋码规则',
options: [{ label: '低值易耗品', value: 2 }, { label: '高价值工具类', value: 1 }]
},
rules: [],
},
{
type: 'input',
group: 'form',
config: {
autoLink: true,
hasFeedback: false,
label: '备注',
name: 'description',
required: false,
},
properties: {
size: 'default',
controls: true,
placeholder: '',
},
rules: [],
}
]

View File

@ -1,322 +1,8 @@
<template>
<!-- steps -->
<div>
<a-steps v-model:current="current" :items="items"></a-steps>
</div>
<a-divider style="height: 2px; background-color: #7cb305" />
<!-- step1 -->
<div class="step-1" v-if="current === 0">
<!-- 基本信息的表单 -->
<div>
<a-form :model="formData" name="basic" layout="horizontal" labelWrap>
<a-form-item label="申请人" name="applicant">
<a-input v-model:value="formData.applicant" style="width: 40%;" />
</a-form-item>
<a-form-item label="申请类型" name="applyType">
<a-radio-group v-model:value="formData.applyType" button-style="solid" style="width: 40%;">
<a-radio-button value=1>采购入库</a-radio-button>
<a-radio-button value=2>归还入库</a-radio-button>
</a-radio-group>
</a-form-item>
<a-form-item label="申请日期" name="applyDate" style="width: 40%;">
<a-date-picker />
</a-form-item>
<a-form-item label="入库物料" name="selected">
<a-select v-model:value="formData.slectedList" mode="multiple" bordered placeholder="请选择入库物料"
style="width: 40%;" showArrow :options="options" @deselect="removeEvent"
@select="insertEvent"></a-select>
</a-form-item>
</a-form>
</div>
<!-- vxe-table -->
<div>
<vxe-table border show-overflow ref="tableRef" max-height="500" :column-config="{ resizable: true }"
size="medium" :data="tableData" empty-text="请先选择入库物料" :edit-config="{ trigger: 'click', mode: 'cell' }"
:checkbox-config="{ trigger: 'row', highlight: true }">
<vxe-column type="seq" title="序号" width="60"></vxe-column>
<vxe-column field="id" title="物料id" :visible="false"></vxe-column>
<vxe-column field="role" title="物料名称" beforeEditMethod="false">
<template #default="{ row }">
<span>{{ row.name }}</span>
</template>
</vxe-column>
<vxe-column field="code" title="编码" beforeEditMethod="false">
<template #edit="{ row }">
<vxe-input v-model="row.code" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="spec" title="规格" beforeEditMethod="false">
<template #edit="{ row }">
<vxe-input v-model="row.spec" type="text" transfer></vxe-input>
</template>
</vxe-column>
<vxe-column field="type" title="类型" beforeEditMethod="false">
<template #edit="{ row }">
<vxe-input v-model="row.type" type="text" transfer>
</vxe-input>
</template>
</vxe-column>
<vxe-column field="assignRule" title="赋码规则" beforeEditMethod="false">
<template #edit="{ row }">
<vxe-input v-model="row.assignRule" type="text" transfer>
</vxe-input>
</template>
</vxe-column>
<vxe-column field="quantity" title="申请数量" :edit-render="{}">
<template #edit="{ row }">
<vxe-number-input v-model="row.quantity" type="integer"></vxe-number-input>
</template>
</vxe-column>
<vxe-column field="oprator" title="操作" beforeEditMethod="false">
<template #default="{ row }">
<vxe-button mode="text" status="error" @click="removeRow(row)">删除</vxe-button>
</template>
</vxe-column>
</vxe-table>
</div>
</div>
<!-- step2 -->
<div class="step-2" v-if="current === 1">
<a-button type="primary" @click="autoInsertOneRow">开始扫码</a-button>
<a-button type="primary" danger @click="" style="left: 20px;">重新扫码</a-button>
<vxe-table border stripe show-overflow ref="applyDetailTableRef" max-height="500"
:column-config="{ resizable: true }" :keyboard-config="{ isEsc: true, isEnter: true }" size="medium"
:data="tableData" empty-text="请先扫码物料体条码" :edit-config="{ trigger: 'click', mode: 'cell', autoFocus: true}">
<vxe-column type="seq" title="序号" width="60"></vxe-column>
<vxe-column field="id" title="物料id" :visible="false"></vxe-column>
<vxe-column field="barcode" title="物料条码" :edit-render="{ name: 'input', autoSelect: true }">
<template #edit="{ row }">
<vxe-input v-model="row.barcode" type="text" class="my-input" transfer></vxe-input>
</template>
</vxe-column>
<vxe-column field="role" title="物料名称" beforeEditMethod="false">
<template #default="{ row }">
<span>{{ row.name }}</span>
</template>
</vxe-column>
<vxe-column field="code" title="编码" beforeEditMethod="false">
<template #edit="{ row }">
<vxe-input v-model="row.code" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="spec" title="规格" beforeEditMethod="false">
<template #edit="{ row }">
<vxe-input v-model="row.spec" type="text" transfer></vxe-input>
</template>
</vxe-column>
<vxe-column field="type" title="类型" beforeEditMethod="false">
<template #edit="{ row }">
<vxe-input v-model="row.type" type="text" transfer>
</vxe-input>
</template>
</vxe-column>
<vxe-column field="oprator" title="操作" beforeEditMethod="false">
<template #default="{ row }">
<vxe-button mode="text" status="error" @click="removeStep2Row(row)">删除</vxe-button>
</template>
</vxe-column>
</vxe-table>
</div>
<!-- 按钮 -->
<a-space wrap class="fixed-button-container">
<a-button type="default" @click="current = current - 1" v-if="current > 0">上一步</a-button>
<a-button type="primary" @click="btnClick" v-if="current < 2">下一步</a-button>
<a-button type="primary" @click="btnClick" v-if="current === 2">提交</a-button>
</a-space>
<apply-page pageType='1'></apply-page>
</template>
<script setup lang="ts">
import { VxeTableInstance } from 'vxe-table'
import api from '@/api'
import { useUserStore } from '@/stores/user'
// steps
const current = ref<number>(0)
const items = [{ title: '录入申请' }, { title: '扫码点货' }, { title: '人工确认' }]
import applyPage from '../component/apply-page.vue';
//
interface FormData {
applicant: string; //
applyDate: Date; //
applyType: number; //
slectedList: string[]; //
}
const userStore = useUserStore()
const formData = ref<FormData>({
applicant: userStore.userName,
applyDate: new Date(),
applyType: 1, // 1: 2: 3:
slectedList: []
});
// vxe-table
interface RowVO {
id: number
name: string
code: string
spec: string
type: string
quantity: number
disabled: boolean
checked: boolean
assignRule: number
}
const tableRef = ref<VxeTableInstance<RowVO>>()
// vxe-table
const tableData = ref<Array<RowVO>>([])
//
const options = ref<{ label: string, value: number }[]>([])
const materialList = ref<material.Material[]>([])
const getMaterialList = async () => {
await api.materialApi.material.all((data) => {
materialList.value = data
})
options.value = materialList.value.map((item) => {
return { label: item.name ? item.name : '未知', value: item.id ? item.id : -1 }
})
}
getMaterialList()
//
// value: number, option: { label: string, value: number }
const insertEvent = (value: string) => {
window.console.log('insertEvent', tableData.value)
// value
const material = materialList.value.find((item) => item.id === (value ? parseInt(value) : -1))
if (material) {
const row: RowVO = {
id: material.id ? material.id : -1,
name: material.name ? material.name : '未知',
code: material.code ? material.code : '未知',
spec: material.spec ? material.spec : '未知',
type: material.type ? material.type : '未知',
quantity: 1,
assignRule: material.assignRule ? material.assignRule : 1,
disabled: false,
checked: false
}
const $table = tableRef.value
if ($table) {
$table.insertAt(row, -1)
}
}
}
// table
const removeEvent = (value: string) => {
const $table = tableRef.value
// value
if ($table) {
$table.getTableData().fullData.forEach((item) => {
if (item.id === (value ? parseInt(value) : -1)) {
$table.remove(item)
}
})
}
}
// table
const removeRow = async (row: RowVO) => {
//tableData
const $table = tableRef.value
if ($table) {
// row.id
formData.value.slectedList.forEach((item, index) => {
if (item.toString() === row.id.toString()) {
formData.value.slectedList.splice(index, 1)
}
})
$table.remove(row)
}
}
//
const btnClick = () => {
//
current.value = current.value + 1; //
};
// step2
interface Step2RowVO {
barcode: string
name: string
code: string
spec: string
type: string
times: Date
}
// table
const applyDetailTableRef = ref<VxeTableInstance<Step2RowVO>>()
// table
const removeStep2Row = async (row: Step2RowVO) => {
const $table = applyDetailTableRef.value
if ($table) {
$table.remove(row)
}
}
//
const autoInsertOneRow = async () => {
const $table = applyDetailTableRef.value
// //
// const fullData = $table?.getTableData().fullData;
if ($table) {
const row: Step2RowVO = {
barcode: '',
name: '',
code: '',
spec: '',
type: '',
times: new Date()
}
$table.insertAt(row, -1)
}
}
</script>
<style scoped>
/* 固定按钮容器样式 */
.fixed-button-container {
position: fixed;
bottom: 80px;
/* 距离底部的距离 */
right: 30px;
/* 距离右侧的距离 */
z-index: 1000;
/* 确保按钮在其他内容之上 */
}
</style>
</script>

View File

@ -0,0 +1,8 @@
<template>
<apply-page pageType='2'></apply-page>
</template>
<script setup lang="ts">
import applyPage from '../component/apply-page.vue';
</script>

View File

@ -0,0 +1,95 @@
<template>
<page-container>
<!-- 页面操作栏 -->
<template #ops>
<a-row>
<a-col :span="18">
<a-input-search v-model:value="searchKey" :placeholder="`请输入`" allow-clear enter-button
@search="loadData()"></a-input-search>
</a-col>
</a-row>
</template>
<!-- 页面表格内容 -->
<div style="min-height: calc(100vh - 305px)">
<!-- 表格行 -->
<a-table :columns="columns" :data-source="pagedata?.records" bordered :pagination="pagination"
:loading="loading" row-key="key">
</a-table>
</div>
</page-container>
</template>
<script setup lang="ts">
import api from '@/api'
import { IPage } from '@/api/api'
const searchKey = ref('')
const pagedata = ref<IPage<material.ApplyForm>>()
const loading = ref(false)
//
const loadData = async (page = 1, size = 10) => {
loading.value = true
api.materialApi.apply.applies(
//1: 2: 3:
{ type: 1, page: page || pagedata.value?.current, size: size || pagedata.value?.size, key: searchKey.value },
(data) => {
loading.value = false
pagedata.value = data
},
)
}
//
loadData()
//
const columns = [
{
title: '类型',
dataIndex: 'type',
},
{
title: '申请人',
dataIndex: 'applicant',
},
{
title: '申请日期',
dataIndex: 'applyDate',
},
{
title: '是否确认',
dataIndex: 'isConfirm',
},
{
title: '创建人',
dataIndex: 'createdBy',
},
{
title: '创建时间',
dataIndex: 'createdTime',
}
]
//
const pagination = computed(() => {
return {
current: pagedata.value?.current,
pageSize: pagedata.value?.size,
total: pagedata.value?.total,
onChange: (page: number, pageSize: number) => {
loadData(page, pageSize)
},
}
})
</script>

View File

@ -0,0 +1,110 @@
<template>
<page-container>
<!-- 页面操作栏 -->
<template #ops>
<a-row>
<a-col :span="18">
<a-input-search
v-model:value="searchKey"
:placeholder="`请输入物料名称`"
allow-clear
enter-button
@search="loadData()"
></a-input-search>
</a-col>
</a-row>
</template>
<!-- 页面表格内容 -->
<div style="min-height: calc(100vh - 305px)">
<!-- 表格行 -->
<a-table
:columns="columns"
:data-source="materialPage?.records"
bordered
:pagination="pagination"
:loading="loading"
row-key="key"
>
<!-- 操作按钮列 -->
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'assignRule'">
{{ record.assignRule === 1 ? '高价值工具类' : '低值易耗品' }} <!-- 这里定义为0和10再回显的时候不展示-->
</template>
</template>
</a-table>
</div>
</page-container>
</template>
<script setup lang="ts">
import api from '@/api'
import { IPage } from '@/api/api'
const searchKey = ref('')
const materialPage = ref<IPage<material.Material>>()
const loading = ref(false)
//
const loadData = async (page = 1, size = 10) => {
loading.value = true
api.materialApi.material.materials(
{ page: page || materialPage.value?.current, size: size || materialPage.value?.size, key: searchKey.value },
(data) => {
loading.value = false
materialPage.value = data
},
)
}
//
loadData()
//
const columns = [
{
title: '物料编码',
dataIndex: 'code',
},
{
title: '物料名称',
dataIndex: 'name',
},
{
title: '物料类型',
dataIndex: 'type',
},
{
title: '物料型号',
dataIndex: 'spec',
},
{
title: '赋码规则',
dataIndex: 'assignRule',
},
{
title: '库存数量',
dataIndex: 'stock',
},
{
title: '备注',
dataIndex: 'description',
}
]
//
const pagination = computed(() => {
return {
current: materialPage.value?.current,
pageSize: materialPage.value?.size,
total: materialPage.value?.total,
onChange: (page: number, pageSize: number) => {
loadData(page, pageSize)
},
}
})
</script>

View File

@ -0,0 +1,95 @@
<template>
<page-container>
<!-- 页面操作栏 -->
<template #ops>
<a-row>
<a-col :span="18">
<a-input-search v-model:value="searchKey" :placeholder="`请输入`" allow-clear enter-button
@search="loadData()"></a-input-search>
</a-col>
</a-row>
</template>
<!-- 页面表格内容 -->
<div style="min-height: calc(100vh - 305px)">
<!-- 表格行 -->
<a-table :columns="columns" :data-source="pagedata?.records" bordered :pagination="pagination"
:loading="loading" row-key="key">
</a-table>
</div>
</page-container>
</template>
<script setup lang="ts">
import api from '@/api'
import { IPage } from '@/api/api'
const searchKey = ref('')
const pagedata = ref<IPage<material.ApplyForm>>()
const loading = ref(false)
//
const loadData = async (page = 1, size = 10) => {
loading.value = true
api.materialApi.apply.applies(
//1: 2: 3:
{ type: 3, page: page || pagedata.value?.current, size: size || pagedata.value?.size, key: searchKey.value },
(data) => {
loading.value = false
pagedata.value = data
},
)
}
//
loadData()
//
const columns = [
{
title: '类型',
dataIndex: 'type',
},
{
title: '申请人',
dataIndex: 'applicant',
},
{
title: '申请日期',
dataIndex: 'applyDate',
},
{
title: '是否确认',
dataIndex: 'isConfirm',
},
{
title: '创建人',
dataIndex: 'createdBy',
},
{
title: '创建时间',
dataIndex: 'createdTime',
}
]
//
const pagination = computed(() => {
return {
current: pagedata.value?.current,
pageSize: pagedata.value?.size,
total: pagedata.value?.total,
onChange: (page: number, pageSize: number) => {
loadData(page, pageSize)
},
}
})
</script>

View File

@ -0,0 +1,93 @@
<template>
<page-container>
<!-- 页面操作栏 -->
<template #ops>
<a-row>
<a-col :span="18">
<a-input-search v-model:value="searchKey" :placeholder="`请输入`" allow-clear enter-button
@search="loadData()"></a-input-search>
</a-col>
</a-row>
</template>
<!-- 页面表格内容 -->
<div style="min-height: calc(100vh - 305px)">
<!-- 表格行 -->
<a-table :columns="columns" :data-source="stocktakingPage?.records" bordered :pagination="pagination"
:loading="loading" row-key="key">
</a-table>
</div>
</page-container>
</template>
<script setup lang="ts">
import api from '@/api';
import { IPage } from '@/api/api'
const searchKey = ref('')
const stocktakingPage = ref<IPage<material.Stocktaking>>()
const loading = ref(false)
//
const loadData = async (page = 1, size = 10) => {
loading.value = true
api.materialApi.stocktaking.stocktakingList({ page, size, key: searchKey.value }, (data) => {
stocktakingPage.value = data
loading.value = false
})
}
//
loadData()
//
const columns = [
{
title: '盘点类型',
dataIndex: 'type',
},
{
title: '盘点日期',
dataIndex: 'date',
},
{
title: '盘点人',
dataIndex: 'operator',
},
{
title: '盘点结果',
dataIndex: 'result',
},
{
title: '任务状态',
dataIndex: 'status',
},
{
title: '审核人',
dataIndex: 'reviewer',
},
{
title: '审核结果',
dataIndex: 'reviewResult',
},
{
title: '异常处理方式',
dataIndex: 'exceptionHandle',
},
{
title: '异常原因',
dataIndex: 'exception',
}
]
//
const pagination = computed(() => {
return {
current: stocktakingPage.value?.current,
pageSize: stocktakingPage.value?.size,
total: stocktakingPage.value?.total,
onChange: (page: number, pageSize: number) => {
loadData(page, pageSize)
},
}
})
</script>

View File

@ -0,0 +1,101 @@
<template>
<page-container>
<!-- 页面操作栏 -->
<template #ops>
<a-row>
<a-col :span="18">
<a-input-search v-model:value="searchKey" :placeholder="`请输入`" allow-clear enter-button
@search="loadData()"></a-input-search>
</a-col>
<a-col :span="6">
<a-button type="primary" style="margin-left: 10px">
<template #icon>
<icon-font type="icon-plus" />
</template>
盘点申请
</a-button>
</a-col>
</a-row>
</template>
<!-- 页面表格内容 -->
<div style="min-height: calc(100vh - 305px)">
<!-- 表格行 -->
<a-table :columns="columns" :data-source="stocktakingPage?.records" bordered :pagination="pagination"
:loading="loading" row-key="key">
</a-table>
</div>
</page-container>
</template>
<script setup lang="ts">
import api from '@/api';
import { IPage } from '@/api/api'
const searchKey = ref('')
const stocktakingPage = ref<IPage<material.Stocktaking>>()
const loading = ref(false)
//
const loadData = async (page = 1, size = 10) => {
loading.value = true
api.materialApi.stocktaking.stocktakingList({ page, size, key: searchKey.value }, (data) => {
stocktakingPage.value = data
loading.value = false
})
}
//
loadData()
//
const columns = [
{
title: '盘点类型',
dataIndex: 'type',
},
{
title: '盘点日期',
dataIndex: 'date',
},
{
title: '盘点人',
dataIndex: 'operator',
},
{
title: '盘点结果',
dataIndex: 'result',
},
{
title: '任务状态',
dataIndex: 'status',
},
{
title: '审核人',
dataIndex: 'reviewer',
},
{
title: '审核结果',
dataIndex: 'reviewResult',
},
{
title: '异常处理方式',
dataIndex: 'exceptionHandle',
},
{
title: '异常原因',
dataIndex: 'exception',
}
]
//
const pagination = computed(() => {
return {
current: stocktakingPage.value?.current,
pageSize: stocktakingPage.value?.size,
total: stocktakingPage.value?.total,
onChange: (page: number, pageSize: number) => {
loadData(page, pageSize)
},
}
})
</script>