Commit dec0aeed by zhuzhequan

Merge branch 'dev' into 'master'

Dev

See merge request !11
parents b517d0c9 f660ae1d
......@@ -22,3 +22,4 @@ dist-ssr
*.njsproj
*.sln
*.sw?
!/src/views/warehouse/manage.vue
......@@ -9,6 +9,7 @@ declare module 'vue' {
export interface GlobalComponents {
CommonCard: typeof import('./src/components/CommonCard.vue')['default']
ElButton: typeof import('element-plus/es')['ElButton']
ElCard: typeof import('element-plus/es')['ElCard']
ElCarousel: typeof import('element-plus/es')['ElCarousel']
ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
......@@ -24,11 +25,14 @@ declare module 'vue' {
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElImage: typeof import('element-plus/es')['ElImage']
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRow: typeof import('element-plus/es')['ElRow']
......@@ -53,6 +57,7 @@ declare module 'vue' {
SplitDiv: typeof import('./src/components/splitDiv/splitDiv.vue')['default']
TableRightMenu: typeof import('./src/components/TableRightMenu.vue')['default']
TableView: typeof import('./src/components/TableView.vue')['default']
UploadExcel: typeof import('./src/components/UploadExcel.vue')['default']
UploadImage: typeof import('./src/components/UploadImage.vue')['default']
WangEditor: typeof import('./src/components/WangEditor.vue')['default']
}
......
......@@ -21,7 +21,8 @@
"vue": "^3.4.19",
"vue-dompurify-html": "^5.1.0",
"vue-router": "^4.3.0",
"vue-tsc": "^2.1.10"
"vue-tsc": "^2.1.10",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@types/splitpanes": "^2.2.6",
......@@ -2509,6 +2510,15 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/adler-32": {
"version": "1.3.1",
"resolved": "https://registry.npmmirror.com/adler-32/-/adler-32-1.3.1.tgz",
"integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==",
"license": "Apache-2.0",
"engines": {
"node": ">=0.8"
}
},
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
......@@ -2714,6 +2724,19 @@
}
]
},
"node_modules/cfb": {
"version": "1.2.2",
"resolved": "https://registry.npmmirror.com/cfb/-/cfb-1.2.2.tgz",
"integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
"license": "Apache-2.0",
"dependencies": {
"adler-32": "~1.3.0",
"crc-32": "~1.2.0"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
......@@ -2754,6 +2777,15 @@
"fsevents": "~2.3.2"
}
},
"node_modules/codepage": {
"version": "1.15.0",
"resolved": "https://registry.npmmirror.com/codepage/-/codepage-1.15.0.tgz",
"integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==",
"license": "Apache-2.0",
"engines": {
"node": ">=0.8"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
......@@ -2800,6 +2832,18 @@
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true
},
"node_modules/crc-32": {
"version": "1.2.2",
"resolved": "https://registry.npmmirror.com/crc-32/-/crc-32-1.2.2.tgz",
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
"license": "Apache-2.0",
"bin": {
"crc32": "bin/crc32.njs"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz",
......@@ -3498,6 +3542,15 @@
"node": ">= 6"
}
},
"node_modules/frac": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/frac/-/frac-1.1.2.tgz",
"integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==",
"license": "Apache-2.0",
"engines": {
"node": ">=0.8"
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
......@@ -4904,6 +4957,18 @@
"url": "https://github.com/sponsors/antoniandre"
}
},
"node_modules/ssf": {
"version": "0.11.2",
"resolved": "https://registry.npmmirror.com/ssf/-/ssf-0.11.2.tgz",
"integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
"license": "Apache-2.0",
"dependencies": {
"frac": "~1.1.2"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/ssr-window": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-3.0.0.tgz",
......@@ -5501,12 +5566,51 @@
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-1.1.2.tgz",
"integrity": "sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng=="
},
"node_modules/wmf": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/wmf/-/wmf-1.0.2.tgz",
"integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==",
"license": "Apache-2.0",
"engines": {
"node": ">=0.8"
}
},
"node_modules/word": {
"version": "0.3.0",
"resolved": "https://registry.npmmirror.com/word/-/word-0.3.0.tgz",
"integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==",
"license": "Apache-2.0",
"engines": {
"node": ">=0.8"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
},
"node_modules/xlsx": {
"version": "0.18.5",
"resolved": "https://registry.npmmirror.com/xlsx/-/xlsx-0.18.5.tgz",
"integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
"license": "Apache-2.0",
"dependencies": {
"adler-32": "~1.3.0",
"cfb": "~1.2.1",
"codepage": "~1.15.0",
"crc-32": "~1.2.1",
"ssf": "~0.11.2",
"wmf": "~1.0.1",
"word": "~0.3.0"
},
"bin": {
"xlsx": "bin/xlsx.njs"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/xml-name-validator": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
......
......@@ -23,7 +23,8 @@
"vue": "^3.4.19",
"vue-dompurify-html": "^5.1.0",
"vue-router": "^4.3.0",
"vue-tsc": "^2.1.10"
"vue-tsc": "^2.1.10",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@types/splitpanes": "^2.2.6",
......
import axios from '@/api/axios.ts'
import { BasePaginationData, BaseRespData } from '@/types/api'
import {
warehouseSearchForm,
InterWarehousePage,
InterWarehouseTree,
InterWarehouseDetail,
InterskuList,
InterWarehouseList,
ILocation,
} from '@/types/api/warehouse'
export interface LogListData {
createTime: string
description: string
createdTime?: string | null
}
export interface PrintData {
code: string
list: {
locationName: string
pickingLocation?: string
skuName?: string
warehouseSku?: string
supplierItemNo?: string
number?: string
}[]
}
export interface factoryWarehouseInfo {
pageSize: number
currentPage: number
total?: number
warehouseId?: string
locationName?: string
remark?: string
idList?: string | number[]
}
export interface ExportFactoryWarehouseInfo {
pageSize?: number
currentPage?: number
total?: number
warehouseId?: string
locationName?: string
remark?: string
idList?: string | number[]
}
export interface WarehouseInventory {
pageSize: number
currentPage: number
total?: number
warehouseId: string
skuName: string
warehouseSku: string
occupyInventory: string
inventoryStart: string
inventoryEnd: string
productNumber: string
freezeInventory: string
inventory: string
usableInventoryStart: string
usableInventoryEnd: string
occupyInventoryEnd: string
occupyInventoryStart: string
}
export interface UpdateDefaulted {
id?: number | string
defaulted: number
}
export interface UpdateStatus {
id?: number
status: number | undefined
}
export interface warehouseInfo {
id?: number | string
name: string
code: string
sort: string
defaulted: number
factoryId?: number
factoryCode?: string
remarks: string
}
export interface WarehouseWarning {
id: number | string
locationCode: string
skuName: string
warehouseSku: string
productNumber: string
number: string
locationName: string
}
export interface positionInfo {
id?: number
warehouseId?: string | number
locationName: string
pickingOrder: string
locationCode: string
warehouseName?: string
status?: number
remark: string
}
export interface positionFormInfo {
id?: number
warehouseId?: number | string
locationName: string
pickingOrder: string
locationCode: string
warehouseName: string
remark: string
status: number
}
interface WarehouseWarningData {
id: number
factoryId: number
warehouseId: number
warehouseName: string
warehouseLocationId: number
locationName: string
warehouseSku: string
skuName: string
unit: string
occupyInventory: number
freezeInventory: number
inventory: number
upperLimit: number
floorLimit: number
productNumber: string
itemSort: number
dataVersion: number
status: number
createTime: string
updateTime: string
}
export function getFactoryLocation(data: factoryWarehouseInfo) {
return axios.post<never, BasePaginationData<positionInfo>>(
'factoryWarehouseLocation/list_page',
data,
)
}
export function exportWarehouseInfo(data: ExportFactoryWarehouseInfo) {
return axios.post<never, BasePaginationData<positionInfo>>(
'factoryWarehouseInventory/inventory',
data,
)
}
export function getFactoryWarehouseInfo(data: factoryWarehouseInfo) {
return axios.post<never, BasePaginationData<warehouseInfo>>(
'factoryWarehouseInfo/list_page',
data,
)
}
export function getWarehouseInventoryInfo(data: WarehouseInventory) {
return axios.post<never, BasePaginationData<WarehouseWarning>>(
'factoryWarehouseInventory/list_page',
data,
)
}
export function createWarehouseApi(data: warehouseInfo) {
return axios.post<never, BaseRespData<never>>(
'/factoryWarehouseInfo/add',
data,
)
}
export function factoryLogWarehouseLog(id: number | string | undefined) {
return axios.get<never, BaseRespData<LogListData[]>>(
'/factoryLogWarehouse/get',
{ params: { id } },
)
}
export function factoryWarehouseInfoPrint(data: PrintData) {
return axios.post<never, BaseRespData<never[]>>(
'/factoryWarehouseInfo/print',
data,
)
}
export function importWarehouseLocation(data: FormData) {
return axios.post<never, BaseRespData<never[]>>(
'/factoryWarehouseLocation/importWarehouseLocation',
data,
)
}
export function factoryWarehouseInventoryPrint(data: PrintData) {
return axios.post<never, BaseRespData<never[]>>(
'/factoryWarehouseInventory/print',
data,
)
}
export function createPositionApi(data: positionInfo) {
return axios.post<never, BaseRespData<never>>(
'/factoryWarehouseLocation/add',
data,
)
}
export function warehouseInfoGetAll() {
return axios.get<never, BaseRespData<warehouseInfo[]>>(
'/factoryWarehouseInfo/getAll',
)
}
export function createWarehouseInventoryApi(data: WarehouseWarningData) {
return axios.post<never, BaseRespData<never>>(
'/factoryWarehouseInventory/add',
data,
)
}
export function updateWarehouseApi(data: positionInfo | UpdateDefaulted) {
return axios.post<never, BaseRespData<never>>(
'/factoryWarehouseInfo/update',
data,
)
}
export function updatePositionApi(data: positionInfo) {
return axios.post<never, BaseRespData<never>>(
'/factoryWarehouseLocation/update',
data,
)
}
export function updatePositionStatusApi(data: UpdateStatus) {
return axios.get<never, BaseRespData<never>>(
'/factoryWarehouseLocation/updateStatus',
{ params: data },
)
}
export function updateWarehouseInventoryApi(data: WarehouseWarningData) {
return axios.post<never, BaseRespData<never>>(
'/factoryWarehouseInventory/update',
data,
)
}
export function deleteWarehouseApi(ids: string) {
return axios.get<never, BaseRespData<never>>('/factoryWarehouseInfo/delete', {
params: { ids },
})
}
export function deleteLocationApi(ids: string) {
return axios.get<never, BaseRespData<never>>(
'/factoryWarehouseLocation/delete',
{
params: { ids },
},
)
}
export function deleteWarehouseInventory(ids: string) {
return axios.get<never, BaseRespData<never>>(
'/factoryWarehouseInventory/delete',
{
params: { ids },
},
)
}
// 入库单
export function warehouseInRecordListPageApi(
data: warehouseSearchForm,
currentPage: number,
pageSize: number,
) {
return axios.post<never, BasePaginationData<InterWarehousePage>>(
'/factory/warehouseInRecord/list_page',
{
...data,
currentPage,
pageSize,
},
)
}
export function rejectInRecordApi({
list,
rejectReason,
}: {
list: WarehouseParams[]
rejectReason: string
}) {
return axios.post<never, BaseRespData<never>>(
'factory/warehouseInRecord/reject',
{
list,
rejectReason,
},
)
}
export function addInRecordApi(form: InterWarehouseDetail) {
return axios.post<never, BaseRespData<never>>(
'factory/warehouseInRecord/add',
{
...form,
},
)
}
export function exportOrder(ids: number[], status: string | number) {
return axios.post<never, BaseRespData<never>>(
'factory/warehouseInRecord/exportData',
{ ids: ids, status },
)
}
export function updateInRecordApi(form: InterWarehouseDetail) {
return axios.post<never, BaseRespData<never>>(
'factory/warehouseInRecord/update',
{
...form,
},
)
}
export function getWarehouseInRecordDetailApi(id: number | undefined) {
return axios.get<never, BaseRespData<InterWarehouseDetail>>(
'factory/warehouseInRecord/get',
{
params: {
id,
},
},
)
}
export function getBySkuApi(warehouseId: number | string, sku: string | null) {
return axios.get<never, BaseRespData<InterskuList[]>>(
'customProductItem/getBySku',
{
params: {
warehouseId,
sku,
},
},
)
}
export function getByWareHouseIdAndCodeApi(
wareHouseId: number | string | undefined,
code: string | null,
) {
return axios.get<never, BaseRespData<ILocation[]>>(
'factoryWarehouseLocation/getByWareHouseIdAndCode',
{
params: {
wareHouseId,
code,
},
},
)
}
export function getInRecordStatusTree() {
return axios.get<never, BaseRespData<InterWarehouseTree[]>>(
'factory/warehouseInRecord/status_tree',
)
}
export function getWarehouseListApi() {
return axios.get<never, BaseRespData<InterWarehouseList[]>>(
'factoryWarehouseInfo/getAll',
)
}
interface WarehouseParams {
id?: number
dataVersion?: number
}
export function auditOrderApi(url: string, data: WarehouseParams[]) {
return axios.post(url, data)
}
export function deleteWarehouseInRecordApi(ids: string) {
return axios.get<never, BaseRespData<never>>(
'factory/warehouseInRecord/delete',
{
params: { ids },
},
)
}
export function getInRecordLogApi(inRecordId?: number) {
return axios.get<never, BaseRespData<LogListData[]>>(
`factory/warehouseInRecord/log/${inRecordId}`,
)
}
// 出库单
export function getOutRecordStatusTree() {
return axios.get<never, BaseRespData<InterWarehouseTree[]>>(
'factory/warehouseOutRecord/status_tree',
)
}
export function warehouseOutRecordListPage(
data: warehouseSearchForm,
currentPage: number,
pageSize: number,
) {
return axios.post<never, BasePaginationData<InterWarehousePage>>(
'factory/warehouseOutRecord/list_page',
{
...data,
currentPage,
pageSize,
},
)
}
export function deleteWarehouseOutRecordApi(ids: string) {
return axios.get<never, BaseRespData<never>>(
'factory/warehouseOutRecord/delete',
{
params: { ids },
},
)
}
<template>
<div
class="image-view"
ref="imageViewRef"
class="image-view"
@mouseover="(ev) => mouseoverImg(ev, src)"
@mouseleave="mouseleaveImg"
>
......
<template>
<div v-loading="loading" class="enhanced-upload">
<div class="import-content">
<div>
<div class="upload-area" @click="triggerFileInput">
<el-icon class="el-icon--upload"><UploadFilled /></el-icon>
<div class="el-upload__text">
将文件拖到此处,或<span style="color: #409eff">点击上传</span>
</div>
</div>
<input
ref="fileInputRef"
type="file"
accept=".xls,.xlsx"
style="display: none"
@change="onFileChange"
/>
<div class="custom-tip">
<span>请上传Excel文件(.xls 或 .xlsx)</span>
</div>
</div>
<div v-if="fileList.length > 0">
<div
v-for="(item, idx) in fileList"
:key="idx"
class="custom-file-item"
>
<el-icon class="file-icon"><Document /></el-icon>
<div class="file-info">
<div
class="file-name"
:title="`点击下载 ${item.path} 文件`"
@click="downloadFile(item.path)"
>
{{ item?.filename || SetFileName(item.path) }}
</div>
</div>
<el-icon class="delete-icon" @click="removeFile(idx)"
><Close
/></el-icon>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import * as XLSX from 'xlsx'
import { ref, watch, defineProps, defineEmits, computed } from 'vue'
import { UploadFilled, Document, Close } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { uploadFileApi } from '@/api/common'
interface FileItem {
path: string
filename?: string
}
const props = defineProps<{
modelValue: string
importType: string
}>()
const emit = defineEmits(['update:modelValue', 'imported'])
const fileList = ref<FileItem[]>([])
const fileInputRef = ref<HTMLInputElement | null>(null)
const loading = ref(false)
const value = computed({
get() {
return props.modelValue
},
set(val: string) {
emit('update:modelValue', val)
},
})
watch(
value,
() => {
let file: FileItem[] = []
if (!Array.isArray(value)) {
if (value.value) {
file.push({ path: value.value })
} else {
file = []
}
}
fileList.value = file
},
{ immediate: true },
)
const triggerFileInput = () => {
if (loading.value) return
fileInputRef.value?.click()
}
const downloadFile = (path: string) => {
window.open(path)
}
const SetFileName = (path: string) => {
if (!path) return ''
const i = path.lastIndexOf('/')
if (i === -1) return path
return path.substring(i + 1)
}
const onFileChange = async (e: Event) => {
const files = (e.target as HTMLInputElement).files
if (!files) return
const file = files[0]
// 校验类型
const isValidType = [
'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
].includes(file.type)
if (!isValidType) {
ElMessage.error('文件类型错误,请上传Excel文件')
return
}
// 校验大小
const isSizeValid = file.size / 1024 / 1024 < 50
if (!isSizeValid) {
ElMessage.error('文件大小不能超过50MB')
return
}
if (props.importType === 'local') {
// 本地解析
const reader = new FileReader()
reader.onload = (evt) => {
const data = evt.target?.result
const workbook = XLSX.read(data, { type: 'binary' })
const firstSheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[firstSheetName]
const jsonData = XLSX.utils.sheet_to_json(worksheet)
//emit 路径和数据
emit('imported', { path: file.name, data: jsonData })
fileList.value = [{ path: file.name, filename: file.name }]
value.value = file.name || ''
ElMessage.success('导入成功')
}
reader.readAsBinaryString(file)
if (fileInputRef.value) fileInputRef.value.value = ''
return
}
// 走原有上传逻辑
await fileUpload(file)
if (fileInputRef.value) fileInputRef.value.value = ''
}
const fileUpload = async (file: File) => {
const formData = new FormData()
const filename = file.name
formData.append('file', file)
formData.append('businessType', 'product')
loading.value = true
try {
const res = await uploadFileApi(formData)
fileList.value = [{ path: res.message ?? '', filename }]
value.value = res.message ?? ''
ElMessage.success('导入成功')
} catch (e) {
ElMessage.error('上传失败')
} finally {
loading.value = false
}
}
const removeFile = (idx: number) => {
fileList.value.splice(idx, 1)
value.value = ''
}
</script>
<style scoped lang="scss">
.enhanced-upload {
.import-content {
padding: 20px 0;
}
.custom-file-item {
display: flex;
align-items: center;
padding: 12px;
border: 1px solid #e8e8e8;
border-radius: 4px;
margin-top: 8px;
background: #fff;
.file-icon {
font-size: 24px;
color: #52c41a;
margin-right: 12px;
}
.file-info {
flex-grow: 1;
.file-name {
color: #333;
margin-bottom: 4px;
}
.file-name:hover {
text-decoration: underline;
color: blue;
}
}
.delete-icon {
color: #f56c6c;
font-size: 20px;
cursor: pointer;
margin-left: 10px;
&:hover {
color: #ff0000;
}
}
}
.upload-area {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: 1px dashed #d9d9d9;
border-radius: 6px;
padding: 40px 20px;
// background: #fafafa;
background: var(--el-fill-color-blank);
cursor: pointer;
&:hover {
border-color: var(--el-color-primary);
}
.el-icon--upload {
font-size: 70px;
color: #a8abb2;
margin-bottom: 12px;
}
.el-upload__text {
color: #666;
}
}
.custom-tip {
display: flex;
align-items: center;
color: #666;
margin-top: 12px;
i {
margin-right: 6px;
}
}
}
</style>
......@@ -86,10 +86,10 @@ const onChange = async (e: Event) => {
const files = (e.target as HTMLInputElement).files
if (!files) return
const file = files[0]
const isLtTenM = file.size / 1024 / 1024 < 200;
const isLtTenM = file.size / 1024 / 1024 < 200
if (!isLtTenM) {
ElMessage.error("上传文件大小不能超过 200MB!");
return isLtTenM;
ElMessage.error('上传文件大小不能超过 200MB!')
return isLtTenM
}
if (props.imageMode) {
imageUpload(file)
......
......@@ -9,6 +9,10 @@ const props = defineProps({
default: '',
type: String || Number,
},
otherSize: {
default: 20,
type: String || Number,
},
})
const domSize = ref<string>('0')
......@@ -51,6 +55,11 @@ defineExpose({
<slot name="bottom"></slot>
</div>
</pane>
<pane v-if="$slots.other" :size="otherSize">
<div id="other-pane">
<slot name="other"></slot>
</div>
</pane>
</splitpanes>
</template>
......@@ -58,7 +67,9 @@ defineExpose({
#top {
height: fit-content;
}
#other-pane{
height: 100%;
}
#bottom {
height: 100%;
}
......
......@@ -16,12 +16,18 @@ import { getToken } from '@/api/axios'
import UserPage from '@/views/UserPage.vue'
import DeliveryNotePage from '@/views/DeliveryNotePage.vue'
import AccountStatementNote from '@/views/AccountStatementNote.vue'
// import Product from '@/views/product/index.vue'
import PodBillOrder from '@/views/podBillOrder/index.vue'
import TypeseetingManagement from '@/views/typesetting/TypesettingManagement.vue'
import PodOrderList from '@/views/order/pod/index.vue'
import PodDeliveryNoteList from '@/views/order/pod/deliveryOrderList.vue'
import PodUsOrderList from '@/views/order/podUs/index.vue'
import WarehouseManage from '@/views/warehouse/manage.vue'
import WarehouseWarning from '@/views/warehouse/warning.vue'
import WarehousePosition from '@/views/warehouse/position.vue'
import receiptDoc from '@/views/warehouse/receiptDoc.vue'
import issueDoc from '@/views/warehouse/issueDoc.vue'
const router = createRouter({
history: createWebHistory(),
routes: [
......@@ -37,6 +43,13 @@ const router = createRouter({
},
component: Dashboard,
},
// {
// path: '/product',
// meta: {
// title: '商品',
// },
// component: Product,
// },
{
path: '/order/list',
meta: {
......@@ -92,7 +105,8 @@ const router = createRouter({
title: '定制对账单',
},
component: AccountStatementNote,
},{
},
{
path: '/account/pod-bill-order',
meta: {
title: 'POD对账单',
......@@ -106,6 +120,40 @@ const router = createRouter({
},
component: TypeseetingManagement,
},
{
path: '/warehouse/manage',
meta: {
title: '仓库管理',
},
component: WarehouseManage,
},
{
path: '/warehouse/receipt-doc',
meta: {
title: '入库单',
},
component: receiptDoc,
},
{
path: '/warehouse/issue-doc',
meta: {
title: '出库单',
},
component: issueDoc,
},
{
path: '/warehouse/warning',
meta: {
title: '仓库预警',
},
component: WarehouseWarning,
},{
path: '/warehouse/position',
meta: {
title: '库位管理',
},
component: WarehousePosition,
},
],
},
// 登录
......
......@@ -11,6 +11,44 @@ const menu: MenuItem[] = [
id: 1,
label: '概览',
},
// {
// index: '/product',
// id: 11,
// label: '商品',
// },
{
index: '13',
id: 13,
label: '库存',
children: [
{
index: '/warehouse/warning',
id: 125,
label: '仓库预警',
},
{
index: '/warehouse/receipt-doc',
id: 123,
label: '入库单',
},
{
index: '/warehouse/issue-doc',
id: 124,
label: '出库单',
},
{
index: '/warehouse/manage',
id: 121,
label: '仓库管理',
},
{
index: '/warehouse/position',
id: 122,
label: '库位管理',
},
],
},
{
index: '1',
id: 2,
......
export interface warehouseSearchForm {
billStatus?: string
batchNumber?: string
createTimeEnd?: string
createTimeStart?: string
orderNumber?: string
sku?: string
warehouseId?: number
id?: number
}
export interface InterProductList {
createTime?: string
id?: number
inId?: number
productNo?: string | null //custom的货号
buyStored?: number | null
remark?: string | null
skuImage?: string
skuName?: string
costPrice?: number | null
totalPrice?: number | null
updateTime?: string
warehouseSku?: string
locationId?: number | null
locationCode?: string | null
[propName: string]: string | number | boolean | undefined | unknown
}
export interface InterWarehouseBase {
id?: number
factoryId?: number
factoryCode?: string
warehouseId?: number | string
warehouseName?: string
inNo?: string
shipmentNumber?: string
skuAmount?: number
total?: number
totalPrice?: number
billStatus?: string
remark?: string | null
dataVersion?: number
createTime?: string | null
updateTime?: string | null
rejectReason?: string | null
}
// 主表列表ts
export interface InterWarehousePage extends InterWarehouseBase {}
// 子表列表ts
export interface InterWarehouseDetail extends InterWarehouseBase {
productList: InterProductList[]
}
export interface InterWarehouseTree {
id?: number
code?: string | null
name?: string
countQuantity?: string | null
children: InterWarehouseTree[] | null
leaf?: boolean
}
export interface InterProductList {
createTime?: string
id?: number
inId?: number
productNo?: string | null //货号
buyStored?: number | null //入库数量
// rejectsAmount?: number
// rejectsReason?: string
remark?: string | null
skuImage?: string
skuName?: string
costPrice?: number | null
totalPrice?: number | null
updateTime?: string
warehouseSku?: string
locationId?: number | null
locationCode?: string | null
}
export interface InterskuList {
id?: number
productId?: number
sku?: string
skuName?: string
image?: string
factoryPrice?: number
productNo?: string | null //货号
locationId?: number | null
locationCode?: string | null
}
export interface InterWarehouseList {
id: number
name: string
code?: string
sort?: number
defaulted?: number
factoryId?: number
factoryCode?: string
remarks?: string | null
}
export interface ILocation {
id?: number
locationId?: number | null
locationCode?: string | null
}
// 允许通用对象类型
export type AnyObject = { [key: string]: unknown }
type IdType = string | number
function itemIsArray(obj: AnyObject): boolean {
for (const key in obj) {
if (Array.isArray(obj[key])) {
return true
}
}
return false
}
function isChange(arr: AnyObject[], arr1: AnyObject[]): boolean {
if (!arr1) return true
if (arr.length !== arr1.length) return true
for (const iterator of arr) {
const item = arr1.find((item: AnyObject) => item.id === iterator.id)
if (!item) return true
}
return false
}
export function checkUpdateParams(
newParams: AnyObject,
oldParams: AnyObject,
id: string = 'id',
other: Record<string, string> = {},
bool: boolean = false
): AnyObject | null {
oldParams = JSON.parse(JSON.stringify(oldParams))
if (!oldParams) return newParams
if ((newParams as { id?: unknown })?.id !== (oldParams as { id?: unknown })?.id) return newParams
const params: AnyObject = {
id: (newParams as { id?: unknown }).id
}
for (const key in newParams) {
if (typeof newParams[key] === 'object') {
if (Array.isArray(newParams[key])) {
const arr: AnyObject[] = newParams[key] as AnyObject[]
const arr1: AnyObject[] = (oldParams[key] as AnyObject[]) || []
const addList: AnyObject[] = []
const updateList: AnyObject[] = []
let removeList: IdType[] = []
const list: AnyObject[] = []
const keyname: string = other[key] || id
for (const iterator of arr) {
const obj: AnyObject = {}
const index = arr1.findIndex((item: AnyObject) => item[keyname] === iterator[keyname])
const isArray = itemIsArray(iterator)
if (index !== -1) {
const item = arr1[index]
arr1.splice(index, 1)
for (const key1 in iterator) {
if (key1 === keyname) continue
if (Array.isArray(iterator[key1])) {
if (isChange(iterator[key1] as AnyObject[], item[key1] as AnyObject[])) {
obj[key1] = iterator[key1]
}
} else if (iterator[key1] !== item[key1]) {
obj[key1] = iterator[key1]
}
}
if (Object.keys(obj).length > 0) {
if (isArray && !bool) {
list.push({
[keyname]: iterator[keyname],
...obj,
id: item.id
})
} else {
updateList.push({
[keyname]: iterator[keyname],
...obj,
id: item.id
})
}
}
} else {
if (isArray && !bool) {
list.push(iterator)
} else {
addList.push(iterator)
}
}
}
if (arr1.length > 0) {
removeList = arr1.map((item: AnyObject) => item['id'] as IdType)
}
const key_name = key.replace('List', 'Change')
params[key_name] = {}
if (addList.length > 0) {
(params[key_name] as AnyObject).addList = addList
}
if (updateList.length > 0) {
(params[key_name] as AnyObject).updateList = updateList
}
if (removeList.length > 0) {
(params[key_name] as AnyObject).removeList = removeList
}
if (list.length > 0) {
params[key_name] = list
}
if (Object.keys(params[key_name] as object).length === 0) {
delete params[key_name]
}
}
} else {
// 基础信息
// if (newParams[key] !== oldParams[key]) {
params[key] = newParams[key]
// }
}
}
if (Object.keys(params).length === 1) {
return null
}
return params
}
\ No newline at end of file
......@@ -10,8 +10,34 @@ export default function useImagePreview() {
img.style.width = '300px'
div.appendChild(img)
document.body.appendChild(div)
let currentTarget: HTMLElement | null = null
const mousemoveHandler = (ev: MouseEvent) => {
if (!currentTarget) return
const rect = currentTarget.getBoundingClientRect()
const inOrigin =
ev.clientX >= rect.left &&
ev.clientX <= rect.right &&
ev.clientY >= rect.top &&
ev.clientY <= rect.bottom
const divRect = div.getBoundingClientRect()
const inPreview =
ev.clientX >= divRect.left &&
ev.clientX <= divRect.right &&
ev.clientY >= divRect.top &&
ev.clientY <= divRect.bottom
if (!inOrigin && !inPreview) {
div.style.display = 'none'
show.value = false
window.removeEventListener('mousemove', mousemoveHandler)
currentTarget = null
}
}
const mouseoverImg = (ev: MouseEvent, url: string) => {
console.log(url, ev.clientY, ev.clientX)
ev.preventDefault()
if (show.value === true) return
img.src = url
......@@ -30,12 +56,16 @@ export default function useImagePreview() {
div.style.top = y + 'px'
div.style.display = 'block'
show.value = true
currentTarget = ev.currentTarget as HTMLElement
window.addEventListener('mousemove', mousemoveHandler)
}
}
const mouseleaveImg = () => {
if (show.value === false) return
div.style.display = 'none'
show.value = false
}
return { mouseoverImg, mouseleaveImg }
}
......@@ -231,7 +231,7 @@
v-if="['TO_BE_CONFIRMED', 'IN_PRODUCTION'].includes(status)"
class="item"
>
<ElButton type="warning" is-dark @click="synchronousPlan">
<ElButton :loading="syncLoading" type="warning" is-dark @click="synchronousPlan">
同步素材图</ElButton
>
</span>
......@@ -321,7 +321,7 @@
: ''
"
class="item-image"
@click="handleChangeImages(item, cardItem)"
@click.stop="handleChangeImages(item, cardItem)"
>
<img :src="item?.image" height="28" />
</div>
......@@ -1731,6 +1731,7 @@ const openAll = (row: CardOrderData) => {
// 表格和卡片的选中值:有两种约束
const selection = ref<(CardOrderData | PodProductList)[]>([])
const tableData = ref<OrderData[]>([])
const syncLoading = ref<boolean>(false)
const handleSelectionChange = (s: CardOrderData[]) => {
selection.value = s
}
......@@ -1813,6 +1814,7 @@ const synchronousPlan = async () => {
offset: window.innerHeight / 2,
})
}
syncLoading.value = true
try {
await showConfirm('是否同步素材图?', {
confirmButtonText: '确认',
......@@ -1826,9 +1828,11 @@ const synchronousPlan = async () => {
const res = await syncSubOrderDesignImages(selection.value.map(item=>item.id))
await loadDiffList()
await loadTabData()
syncLoading.value = false
ElMessage.success(res.message)
} catch (e) {
// showError(e)
syncLoading.value = false
}
}
// 下载稿件
......
<script setup lang="ts">
import { reactive, ref } from 'vue'
import cardWrapper from './cardWrapper.vue'
const queryParams = reactive({
name: "",
sku: "",
diy_sku: "",
print_type: "",
category_id: "",
});
const pager = reactive({
page:1,
size:100,
loading: false ,
count: 0,
lists: [] ,
extend: {}
})
const setCurrentImg = (item: any, val: string) => {
item.img_url = val;
};
const categoryTree = ref([])
const resetPage = () => {
}
</script>
<template>
<div class="product">
<el-card>
<el-form
ref="formRef"
class="searchForm"
label-width="80px"
:model="queryParams"
:inline="true"
>
<el-form-item label="商品名称">
<el-input
v-model="queryParams.name"
clearable
maxlength="40"
style="width: 150px"
show-word-limit
placeholder="请输入商品名称"
/>
</el-form-item>
<el-form-item label="SKU">
<el-input
v-model="queryParams.sku"
clearable
style="width: 150px"
placeholder="请输入sku"
/>
</el-form-item>
<el-form-item label="印花类型">
<el-select
v-model="queryParams.print_type"
style="width: 150px"
clearable
placeholder="请选择"
>
<el-option
v-for="(item, index) in ['满印', '局部印']"
:key="index"
:label="item"
:value="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="商品分类">
<el-cascader
ref="categoryCascader"
v-model="queryParams.category_id"
:options="categoryTree"
clearable
style="width: 150px"
:props="{
label: 'name',
value: 'id',
emitPath: false,
}"
:show-all-levels="false"
></el-cascader>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
</el-form-item>
</el-form>
</el-card>
<div class="product-list">
<el-card
style="flex: 1; flex-shrink: 0; overflow: hidden"
class="!border-none"
shadow="never"
>
<div
v-loading="pager.loading"
class="eltable"
element-loading-text="加载中..."
>
<div v-if="pager.lists.length > 0" id="shopline" class="card-mode">
<div
v-for="(item, index) in pager.lists"
:key="index"
class="card-item"
>
<card-wrapper
:data="item"
:index="index"
is-show-home-sku="bottom"
:is-sku-image-list="true"
:has-width="true"
:is-show-sku="false"
:is-show-sales="false"
:is-custom="true"
@set-current-img="(val) => setCurrentImg(item, val)"
>
<template #operations>
<!-- <img-->
<!-- title="操作日志"-->
<!-- width="24"-->
<!-- height="24"-->
<!-- src="@/assets/images/log.png"-->
<!-- alt=""-->
<!-- @click.stop="viewTheLog(item.id)"-->
<!-- />-->
<img
title="编辑"
width="24"
height="24"
src="@/assets/images/edit.png"
alt=""
@click.stop="editInfo(item, 'edit')"
/>
</template>
<template #price>
<span
style="margin: 0 5px"
class="price"
:title="'建议零售价' + item.sales_price"
>
{{ item.sales_price ? "¥" : ""
}}{{ item.sales_price }}&nbsp;
</span>
</template>
<template #level-time>
<div
class="create-time"
:title="`上架时间:${item.create_time}`"
>
<span>{{ item.create_time }}</span>
</div>
</template>
<template #synthesizeStatus>
<div title="印花状态" style="position: absolute; right: 0">
<el-tag :type="item.print_type == 0 ? '' : 'warning'">
{{ item.print_type == 0 ? "满印" : "局部印" }}
</el-tag>
</div>
</template>
<template #otherContent>
<div class="sds-keyid">
<div class="product-id" @click.stop="copy(item.id)">
<img
:title="'复制' + item.id"
width="20"
src="@/assets/images/id.png"
alt=""
/>
<span :title="item.id">
{{ item.id }}
</span>
</div>
<div class="product-sku" @click.stop="copy(item.sku)">
<span :title="item.sku">
{{ item.sku }}
</span>
</div>
</div>
</template>
</card-wrapper>
</div>
</div>
<div v-else class="empty">暂无数据</div>
</div>
<div class="flex justify-center mt-4">
<div
style="
display: flex;
align-items: center;
margin-left: 20px;
width: max-content;
"
>
<span>一行展示</span>
<el-input
v-model="rowNumber"
type="number"
style="width: 80px; margin: 0 10px"
placeholder="请输入"
clearable
@change="changeRowNumber"
/>
<span>条</span>
</div>
&emsp;&emsp;&emsp;
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
</div>
</div>
</template>
<style scoped lang="scss">
.product{
display: flex;
flex-direction: column;
height: 100%;
}
.searchForm{
::v-deep(.el-form-item){
margin-bottom: 0;
}
}
.justify-center{
display: flex;
justify-content: center;
}
.product-list{
flex: 1;
margin-top: 10px;
flex-shrink: 0;
::v-deep(.el-card){
height: 100%;
.el-card__body{
display: flex;
height: 100%;
flex-direction: column;
.eltable{
flex: 1;
flex-shrink: 0;
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
</style>
<script setup lang="ts">
import {
getFactoryWarehouseInfo,
factoryWarehouseInfo,
warehouseInfo,
createWarehouseApi,
updateWarehouseApi, deleteWarehouseApi,
} from '@/api/warehouse.ts'
import { nextTick, ref } from 'vue'
const selections = ref<warehouseInfo[]>([])
const formRef = ref()
const createData = ref({
title: '',
show: false,
isEdit: false,
form: {
name: '',
code: '',
sort: '',
defaulted: 0,
remarks: '',
},
})
const rules = {
name: [
{ required: true, message: '请输入仓库名称', trigger: 'blur' },
],
code: [
{ required: true, message: '请输入仓库编码', trigger: 'blur' },
],
defaulted: [
{ required: true, message: '请选择是否默认仓库', trigger: 'change' },
],
}
const leftData = ref<warehouseInfo[]>([])
const pagination = ref<factoryWarehouseInfo>({
pageSize: 50,
currentPage: 1,
total: 0,
})
async function getData() {
const res = await getFactoryWarehouseInfo({
...pagination.value,
})
leftData.value = res.data.records
pagination.value.total = res.data.total
}
const handleSelectionChange = (data: warehouseInfo[]) => {
selections.value = data
}
const handleSizeChange = (pageSize: number) => {
pagination.value.pageSize = pageSize
getData()
}
const handleCurrentChange = (currentPage: number) => {
pagination.value.currentPage = currentPage
getData()
}
const handleConfirm = async () => {
await formRef.value?.validate()
if (!createData.value.isEdit) {
await createWarehouseApi(createData.value.form)
} else {
await updateWarehouseApi(createData.value.form)
}
createData.value.show = false
ElMessage.success('操作成功')
await getData()
}
const handleBatchDelete = async () => {
if (!selections.value.length) {
return ElMessage.warning('请选择要删除的数据')
}
await ElMessageBox.confirm('确定要删除吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
const str = selections.value.map((el) => el.id).join(',')
try {
await deleteWarehouseApi(str)
ElMessage.success('删除成功')
await getData()
} catch (error) {
await getData()
}
}
const createWarehouse = () => {
createData.value.show = true
createData.value.isEdit = false
createData.value.title = '新增仓库'
createData.value.form = {
name: '',
code: '',
sort: '',
defaulted: 0,
remarks: '',
}
nextTick(() => {
formRef.value?.clearValidate()
})
}
const updateDefaulted = async (item: warehouseInfo) => {
await updateWarehouseApi({
id: item.id,
defaulted: item.defaulted,
})
await getData()
}
const updateWarehouse = (item: warehouseInfo) => {
createData.value.show = true
createData.value.isEdit = true
createData.value.title = '修改仓库'
createData.value.form = { ...item }
nextTick(() => {
formRef.value?.clearValidate()
})
}
getData()
</script>
<template>
<el-card style="height: 100%">
<div class="manage">
<div class="header">
<el-button type="success" @click="createWarehouse">新增仓库</el-button>
<el-button type="danger" @click="handleBatchDelete">删除</el-button>
</div>
<div class="table-flex">
<div class="left-table">
<div class="table-container">
<el-table height="100%" :data="leftData" border @selection-change="handleSelectionChange">
<el-table-column type="selection" />
<el-table-column type="index" label="序号" width="60" />
<el-table-column label="仓库名称" prop="name" align="center" />
<el-table-column label="仓库编码" prop="code" align="center" />
<el-table-column label="仓库序号" prop="sort" align="center" />
<el-table-column label="备注" prop="remarks" align="center" />
<el-table-column label="默认仓库" prop="defaulted" align="center">
<template #default="{row}">
<el-switch
v-model="row.defaulted" :active-value="1" :inactive-value="0"
@click="updateDefaulted(row)"></el-switch>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template #default="{row}">
<el-button type="primary" @click="updateWarehouse(row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="pagination">
<el-pagination
v-model:current-page="pagination.currentPage"
v-model:page-size="pagination.pageSize"
:page-sizes="[50, 100, 150, 200]"
layout="total, sizes, prev, pager, next, jumper"
:total="pagination.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</div>
<el-dialog v-model="createData.show" :title="createData.title">
<el-form ref="formRef" label-width="110px" :rules="rules" :model="createData.form">
<el-form-item label="仓库名称" prop="name">
<el-input v-model="createData.form.name" clearable placeholder="请输入仓库名称"></el-input>
</el-form-item>
<el-form-item label="仓库编码" prop="code">
<el-input v-model="createData.form.code" clearable placeholder="请输入仓库编码"></el-input>
</el-form-item>
<el-form-item label="仓库序号" prop="sort">
<el-input-number v-model="createData.form.sort"></el-input-number>
</el-form-item>
<el-form-item label="是否默认仓库" prop="defaulted">
<el-switch v-model="createData.form.defaulted" :active-value="1" :inactive-value="0"></el-switch>
</el-form-item>
<el-form-item label="备注" prop="remarks">
<el-input
v-model="createData.form.remarks" type="textarea" :rows="4" clearable
placeholder="请输入备注"></el-input>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="createData.show=false">取消</el-button>
<el-button type="primary" @click="handleConfirm">确定</el-button>
</template>
</el-dialog>
</div>
</el-card>
</template>
<style scoped lang="scss">
.el-card {
::v-deep(.el-card__body) {
height: 100%;
}
}
.manage {
height: 100%;
display: flex;
flex-direction: column;
.header {
margin-bottom: 10px;
}
.table-flex {
flex: 1;
flex-shrink: 0;
overflow: hidden;
display: flex;
}
.right-table {
flex: 1;
margin-left: 10px;
flex-shrink: 0;
}
.left-table {
height: 100%;
display: flex;
width: 100%;
flex-direction: column;
.pagination {
display: flex;
margin-top: 10px;
justify-content: center;
}
.table-container {
flex: 1;
flex-shrink: 0;
overflow: hidden;
}
}
}
</style>
......@@ -7,6 +7,15 @@ import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
base: '/',
server: {
port: 9803,
host: true,
proxy: {
"/api": {
target: "http://10.168.31.230:8060"
}
}
},
plugins: [
vue(),
AutoImport({
......
// vite.config.ts
import { defineConfig } from "file:///C:/work/factory_front/node_modules/vite/dist/node/index.js";
import AutoImport from "file:///C:/work/factory_front/node_modules/unplugin-auto-import/dist/vite.js";
import Components from "file:///C:/work/factory_front/node_modules/unplugin-vue-components/dist/vite.js";
import { ElementPlusResolver } from "file:///C:/work/factory_front/node_modules/unplugin-vue-components/dist/resolvers.js";
import vue from "file:///C:/work/factory_front/node_modules/@vitejs/plugin-vue/dist/index.mjs";
var vite_config_default = defineConfig({
base: "./",
server: {
port: 9803,
host: true,
proxy: {
"/api": {
target: "http://192.168.31.40:8060"
}
}
},
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()]
}),
Components({
resolvers: [ElementPlusResolver()]
})
],
resolve: {
alias: { "@": "/src" }
}
});
export {
vite_config_default as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJDOlxcXFx3b3JrXFxcXGZhY3RvcnlfZnJvbnRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkM6XFxcXHdvcmtcXFxcZmFjdG9yeV9mcm9udFxcXFx2aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vQzovd29yay9mYWN0b3J5X2Zyb250L3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcbmltcG9ydCBBdXRvSW1wb3J0IGZyb20gJ3VucGx1Z2luLWF1dG8taW1wb3J0L3ZpdGUnXG5pbXBvcnQgQ29tcG9uZW50cyBmcm9tICd1bnBsdWdpbi12dWUtY29tcG9uZW50cy92aXRlJ1xuaW1wb3J0IHsgRWxlbWVudFBsdXNSZXNvbHZlciB9IGZyb20gJ3VucGx1Z2luLXZ1ZS1jb21wb25lbnRzL3Jlc29sdmVycydcbmltcG9ydCB2dWUgZnJvbSAnQHZpdGVqcy9wbHVnaW4tdnVlJ1xuXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcbiAgYmFzZTogJy4vJyxcbiAgc2VydmVyOiB7XG4gICAgcG9ydDogOTgwMyxcbiAgICBob3N0OiB0cnVlLFxuICAgIHByb3h5OiB7XG4gICAgICAnL2FwaSc6IHtcbiAgICAgICAgdGFyZ2V0OiAnaHR0cDovLzE5Mi4xNjguMzEuNDA6ODA2MCcsXG4gICAgICB9LFxuICAgIH0sXG4gIH0sXG4gIHBsdWdpbnM6IFtcbiAgICB2dWUoKSxcbiAgICBBdXRvSW1wb3J0KHtcbiAgICAgIHJlc29sdmVyczogW0VsZW1lbnRQbHVzUmVzb2x2ZXIoKV0sXG4gICAgfSksXG4gICAgQ29tcG9uZW50cyh7XG4gICAgICByZXNvbHZlcnM6IFtFbGVtZW50UGx1c1Jlc29sdmVyKCldLFxuICAgIH0pLFxuICBdLFxuICByZXNvbHZlOiB7XG4gICAgYWxpYXM6IHsgJ0AnOiAnL3NyYycgfSxcbiAgfSxcbn0pXG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQXVQLFNBQVMsb0JBQW9CO0FBQ3BSLE9BQU8sZ0JBQWdCO0FBQ3ZCLE9BQU8sZ0JBQWdCO0FBQ3ZCLFNBQVMsMkJBQTJCO0FBQ3BDLE9BQU8sU0FBUztBQUdoQixJQUFPLHNCQUFRLGFBQWE7QUFBQSxFQUMxQixNQUFNO0FBQUEsRUFDTixRQUFRO0FBQUEsSUFDTixNQUFNO0FBQUEsSUFDTixNQUFNO0FBQUEsSUFDTixPQUFPO0FBQUEsTUFDTCxRQUFRO0FBQUEsUUFDTixRQUFRO0FBQUEsTUFDVjtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQUEsRUFDQSxTQUFTO0FBQUEsSUFDUCxJQUFJO0FBQUEsSUFDSixXQUFXO0FBQUEsTUFDVCxXQUFXLENBQUMsb0JBQW9CLENBQUM7QUFBQSxJQUNuQyxDQUFDO0FBQUEsSUFDRCxXQUFXO0FBQUEsTUFDVCxXQUFXLENBQUMsb0JBQW9CLENBQUM7QUFBQSxJQUNuQyxDQUFDO0FBQUEsRUFDSDtBQUFBLEVBQ0EsU0FBUztBQUFBLElBQ1AsT0FBTyxFQUFFLEtBQUssT0FBTztBQUFBLEVBQ3ZCO0FBQ0YsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment