文件上传组件
parent
8ba12ded82
commit
29d808402d
|
|
@ -1,5 +1,5 @@
|
||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh">
|
<html lang="zh-CN" spellcheck="false">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import {
|
||||||
} from '@/common/utils/http-util.ts'
|
} from '@/common/utils/http-util.ts'
|
||||||
|
|
||||||
import { saveFile } from '@/common/app'
|
import { saveFile } from '@/common/app'
|
||||||
|
import { serverBaseUrl } from '@/common'
|
||||||
|
|
||||||
interface PresignedUrl extends Record<string, string | undefined> {
|
interface PresignedUrl extends Record<string, string | undefined> {
|
||||||
url?: string
|
url?: string
|
||||||
|
|
@ -54,10 +55,12 @@ export default {
|
||||||
if (filename == null || filename.length <= 0) {
|
if (filename == null || filename.length <= 0) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
if (filename.startsWith('http') || filename.startsWith('https')) {
|
if (filename.startsWith('http') || filename.startsWith('https') || filename.startsWith('blob')) {
|
||||||
return filename
|
return filename
|
||||||
}
|
}
|
||||||
if (filename.startsWith('/')) {
|
if (filename.startsWith(serverBaseUrl + '/oss/download')) {
|
||||||
|
return filename
|
||||||
|
} else if (filename.startsWith('/')) {
|
||||||
return getFileUrl('/oss/download' + filename)
|
return getFileUrl('/oss/download' + filename)
|
||||||
} else {
|
} else {
|
||||||
return getFileUrl('/oss/download/' + filename)
|
return getFileUrl('/oss/download/' + filename)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ export const appName = import.meta.env.VITE_APP_NAME
|
||||||
/**
|
/**
|
||||||
* 服务器基础地址
|
* 服务器基础地址
|
||||||
*/
|
*/
|
||||||
export const serverBaseUrl = import.meta.env.VITE_HTTP_SERVER_BASE_URL ?? '/'
|
export const serverBaseUrl = import.meta.env.VITE_HTTP_SERVER_BASE_URL ?? ''
|
||||||
|
|
||||||
export const wsServerBaseUrl = import.meta.env.VITE_WS_SERVER_BASE_URL ?? '/'
|
export const wsServerBaseUrl = import.meta.env.VITE_WS_SERVER_BASE_URL ?? '/'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -202,20 +202,63 @@ function prettyDuration(date: DateTime<true | false> | Date | number | string, o
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function endOfMonth(date?: DateTime<true | false>) {
|
function beginOfDay(date?: DateTime<true | false>) {
|
||||||
if (date == null) {
|
if (date == null) {
|
||||||
return date = now()
|
date = now()
|
||||||
}
|
}
|
||||||
return date.endOf('month')
|
return date.startOf('day')
|
||||||
|
}
|
||||||
|
|
||||||
|
function endOfDay(date?: DateTime<true | false>) {
|
||||||
|
if (date == null) {
|
||||||
|
date = now()
|
||||||
|
}
|
||||||
|
return date.endOf('day')
|
||||||
}
|
}
|
||||||
|
|
||||||
function beginOfMonth(date?: DateTime<true | false>) {
|
function beginOfMonth(date?: DateTime<true | false>) {
|
||||||
if (date == null) {
|
if (date == null) {
|
||||||
return date = now()
|
date = now()
|
||||||
}
|
}
|
||||||
return date.startOf('month')
|
return date.startOf('month')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function endOfMonth(date?: DateTime<true | false>) {
|
||||||
|
if (date == null) {
|
||||||
|
date = now()
|
||||||
|
}
|
||||||
|
return date.endOf('month')
|
||||||
|
}
|
||||||
|
|
||||||
|
function beginOfWeek(date?: DateTime<true | false>) {
|
||||||
|
if (date == null) {
|
||||||
|
date = now()
|
||||||
|
}
|
||||||
|
return date.startOf('week')
|
||||||
|
}
|
||||||
|
|
||||||
|
function endOfWeek(date?: DateTime<true | false>) {
|
||||||
|
if (date == null) {
|
||||||
|
date = now()
|
||||||
|
}
|
||||||
|
return date.endOf('week')
|
||||||
|
}
|
||||||
|
|
||||||
|
function beginOfYear(date?: DateTime<true | false>) {
|
||||||
|
if (date == null) {
|
||||||
|
date = now()
|
||||||
|
}
|
||||||
|
return date.startOf('year')
|
||||||
|
}
|
||||||
|
|
||||||
|
function endOfYear(date?: DateTime<true | false>) {
|
||||||
|
if (date == null) {
|
||||||
|
date = now()
|
||||||
|
}
|
||||||
|
return date.endOf('year')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function toDate(date: DateTime<true | false>) {
|
function toDate(date: DateTime<true | false>) {
|
||||||
return date.toJSDate()
|
return date.toJSDate()
|
||||||
}
|
}
|
||||||
|
|
@ -228,6 +271,12 @@ export default {
|
||||||
FMT,
|
FMT,
|
||||||
endOfMonth,
|
endOfMonth,
|
||||||
beginOfMonth,
|
beginOfMonth,
|
||||||
|
beginOfDay,
|
||||||
|
endOfDay,
|
||||||
|
beginOfWeek,
|
||||||
|
endOfWeek,
|
||||||
|
beginOfYear,
|
||||||
|
endOfYear,
|
||||||
toDate,
|
toDate,
|
||||||
prettyDuration,
|
prettyDuration,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ const searchForm = Utils.resetAble(reactive<F>({
|
||||||
const tableData = Utils.resetAble(reactive<TT[]>([])) as ResetAble<TT[]>
|
const tableData = Utils.resetAble(reactive<TT[]>([])) as ResetAble<TT[]>
|
||||||
const totalCount = ref(0)
|
const totalCount = ref(0)
|
||||||
const loading = ref<boolean>(false)
|
const loading = ref<boolean>(false)
|
||||||
const showSearchForm = ref<boolean>(true)
|
const showSearchForm = ref<boolean>(false)
|
||||||
|
|
||||||
function doReset() {
|
function doReset() {
|
||||||
searchForm.$reset()
|
searchForm.$reset()
|
||||||
|
|
@ -182,7 +182,18 @@ onMounted(doSearch)
|
||||||
<button style="display: none" type="submit"></button>
|
<button style="display: none" type="submit"></button>
|
||||||
</ElForm>
|
</ElForm>
|
||||||
<ElTooltip content="刷新" placement="top">
|
<ElTooltip content="刷新" placement="top">
|
||||||
<ElButton :icon="elIcons.Refresh" :loading="loading" type="default" @click="doSearch"/>
|
<ElDropdown split-button @click="doSearch" @command="(command)=>{
|
||||||
|
if(command === 'reset'){
|
||||||
|
doReset()
|
||||||
|
}
|
||||||
|
}">
|
||||||
|
<ElButton :icon="elIcons.Refresh" :loading="loading" type="default"/>
|
||||||
|
<template #dropdown>
|
||||||
|
<ElDropdownMenu slot="dropdown">
|
||||||
|
<ElDropdownItem command="reset">重置并刷新</ElDropdownItem>
|
||||||
|
</ElDropdownMenu>
|
||||||
|
</template>
|
||||||
|
</ElDropdown>
|
||||||
</ElTooltip>
|
</ElTooltip>
|
||||||
<template v-if="!Colls.isEmpty(rightTools)">
|
<template v-if="!Colls.isEmpty(rightTools)">
|
||||||
<ElButton v-for="(tool,i) in rightTools" :key="'tool-bar-right-'+i"
|
<ElButton v-for="(tool,i) in rightTools" :key="'tool-bar-right-'+i"
|
||||||
|
|
@ -405,15 +416,27 @@ onMounted(doSearch)
|
||||||
//box-shadow: rgba(0, 0, 0, 0.12) 0px 0px 12px 0px;
|
//box-shadow: rgba(0, 0, 0, 0.12) 0px 0px 12px 0px;
|
||||||
//padding 10px
|
//padding 10px
|
||||||
|
|
||||||
:deep(.el-form) {
|
.tool-bar-left {
|
||||||
.el-form-item {
|
flex 1
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
& > div:last-child {
|
.tool-bar-right {
|
||||||
|
flex 1
|
||||||
display flex
|
display flex
|
||||||
gap 10px
|
gap 10px
|
||||||
|
justify-content end
|
||||||
|
|
||||||
|
|
||||||
|
:deep(.el-form) {
|
||||||
|
display flex
|
||||||
|
gap 10px
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
margin: 0;
|
||||||
|
flex 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.el-button--default) {
|
:deep(.el-button--default) {
|
||||||
width 32px
|
width 32px
|
||||||
|
|
|
||||||
|
|
@ -9,22 +9,31 @@ import { serverBaseUrl } from '@/common'
|
||||||
import { type R } from '@/common/utils/http-util.ts'
|
import { type R } from '@/common/utils/http-util.ts'
|
||||||
import Strings from '@/common/utils/strings.ts'
|
import Strings from '@/common/utils/strings.ts'
|
||||||
import AppApi from '@/common/app/app-api.ts'
|
import AppApi from '@/common/app/app-api.ts'
|
||||||
|
import type { UploadProps } from 'element-plus/es/components/upload/src/upload'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
files?: string[]
|
files?: string[]
|
||||||
file?: string
|
file?: string
|
||||||
limit: number
|
limit?: number
|
||||||
}>()
|
uploadProps?: Partial<Omit<UploadProps, 'httpRequest' | 'crossorigin' | 'multiple'
|
||||||
|
| 'data' | 'action' | 'headers' | 'limit' | 'onError'
|
||||||
|
| 'onRemove' | 'onSuccess' | 'onPreview' | 'fileList' | 'beforeUpload' | 'beforeRemove' | 'onChange' | 'onProgress' | 'name'>>
|
||||||
|
}>(), {
|
||||||
|
limit: 1,
|
||||||
|
// @ts-ignore
|
||||||
|
uploadProps: {},
|
||||||
|
})
|
||||||
|
|
||||||
|
const multiple = computed(() => props.limit > 1)
|
||||||
const emit = defineEmits([ 'update:files', 'update:file' ])
|
const emit = defineEmits([ 'update:files', 'update:file' ])
|
||||||
const appUserStore = useAppUserStore()
|
const appUserStore = useAppUserStore()
|
||||||
|
const showPreview = ref(false)
|
||||||
const headers = computed(() => ({
|
const headers = computed(() => ({
|
||||||
Authorization: appUserStore.token!,
|
Authorization: appUserStore.token!,
|
||||||
}))
|
}))
|
||||||
const uploadUrl = serverBaseUrl + '/oss/upload'
|
const uploadUrl = serverBaseUrl + '/oss/upload'
|
||||||
|
|
||||||
const files = ref<UploadUserFile[]>([])
|
const filesList = ref<UploadUserFile[]>([])
|
||||||
|
|
||||||
function uploadSuccHandler(response: R<string>, _: UploadFile, uploadFiles: UploadFiles) {
|
function uploadSuccHandler(response: R<string>, _: UploadFile, uploadFiles: UploadFiles) {
|
||||||
if (props.limit === 1) {
|
if (props.limit === 1) {
|
||||||
|
|
@ -38,7 +47,7 @@ function uploadSuccHandler(response: R<string>, _: UploadFile, uploadFiles: Uplo
|
||||||
function rmFileHandler(_: UploadFile, uploadFiles: UploadFiles) {
|
function rmFileHandler(_: UploadFile, uploadFiles: UploadFiles) {
|
||||||
if (props.limit === 1) {
|
if (props.limit === 1) {
|
||||||
if (uploadFiles.length > 0) {
|
if (uploadFiles.length > 0) {
|
||||||
emit('update:file', (files.value[0].response as R<string>).data)
|
emit('update:file', (filesList.value[0].response as R<string>).data)
|
||||||
} else {
|
} else {
|
||||||
emit('update:file', undefined)
|
emit('update:file', undefined)
|
||||||
}
|
}
|
||||||
|
|
@ -52,6 +61,11 @@ function uploadFailHandler(response: any, uploadFile: UploadFile, uploadFiles: U
|
||||||
console.log(response, uploadFile, uploadFiles)
|
console.log(response, uploadFile, uploadFiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const previewList = computed(() => filesList.value.map(it => AppApi.fileUrl(it.url)))
|
||||||
|
const handlePictureCardPreview = () => {
|
||||||
|
console.log(previewList.value, filesList.value)
|
||||||
|
showPreview.value = true
|
||||||
|
}
|
||||||
defineExpose({
|
defineExpose({
|
||||||
setDefaultFiles(urls: string[]) {
|
setDefaultFiles(urls: string[]) {
|
||||||
if (urls.length > 0) {
|
if (urls.length > 0) {
|
||||||
|
|
@ -60,7 +74,7 @@ defineExpose({
|
||||||
if (Strings.isBlank(url)) {
|
if (Strings.isBlank(url)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
files.value?.push({
|
filesList.value?.push({
|
||||||
uid: i,
|
uid: i,
|
||||||
name: url.substring(url.lastIndexOf('/') + 1),
|
name: url.substring(url.lastIndexOf('/') + 1),
|
||||||
url: AppApi.fileUrl(url),
|
url: AppApi.fileUrl(url),
|
||||||
|
|
@ -76,18 +90,53 @@ defineExpose({
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ElUpload
|
<ElUpload
|
||||||
v-model:file-list="files"
|
v-model:file-list="filesList"
|
||||||
:action="uploadUrl"
|
:action="uploadUrl"
|
||||||
:headers="headers"
|
:headers="headers"
|
||||||
:limit="limit"
|
:limit="limit"
|
||||||
|
:multiple="multiple"
|
||||||
:on-error="uploadFailHandler"
|
:on-error="uploadFailHandler"
|
||||||
:on-remove="rmFileHandler"
|
:on-remove="rmFileHandler"
|
||||||
:on-success="uploadSuccHandler"
|
:on-success="uploadSuccHandler"
|
||||||
v-bind="$attrs">
|
:on-preview="handlePictureCardPreview"
|
||||||
<slot/>
|
class="a-uploader"
|
||||||
|
v-bind="uploadProps">
|
||||||
|
<slot>
|
||||||
|
<ElIcon class="default-icon">
|
||||||
|
<ElIconPlus/>
|
||||||
|
</ElIcon>
|
||||||
|
</slot>
|
||||||
|
<template #tip>
|
||||||
|
<slot name="tip"/>
|
||||||
|
</template>
|
||||||
</ElUpload>
|
</ElUpload>
|
||||||
|
<ElImageViewer
|
||||||
|
v-if="showPreview"
|
||||||
|
:url-list="previewList"
|
||||||
|
show-progress
|
||||||
|
style="position: absolute"
|
||||||
|
@close="showPreview = false"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
|
.a-uploader {
|
||||||
|
:deep(.el-upload) {
|
||||||
|
background-color white
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-upload-dragger) {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
border: none;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.default-icon {
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
// ------
|
// ------
|
||||||
// Generated by unplugin-vue-components
|
// Generated by unplugin-vue-components
|
||||||
// Read more: https://github.com/vuejs/core/pull/3399
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
import { GlobalComponents } from 'vue'
|
|
||||||
|
|
||||||
export {}
|
export {}
|
||||||
|
|
||||||
|
|
@ -33,8 +32,12 @@ declare module 'vue' {
|
||||||
ElHeader: typeof import('element-plus/es')['ElHeader']
|
ElHeader: typeof import('element-plus/es')['ElHeader']
|
||||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||||
ElIconCircleClose: typeof import('@element-plus/icons-vue')['CircleClose']
|
ElIconCircleClose: typeof import('@element-plus/icons-vue')['CircleClose']
|
||||||
|
ElIconCirclePlus: typeof import('@element-plus/icons-vue')['CirclePlus']
|
||||||
|
ElIconDelete: typeof import('@element-plus/icons-vue')['Delete']
|
||||||
ElIconPicture: typeof import('@element-plus/icons-vue')['Picture']
|
ElIconPicture: typeof import('@element-plus/icons-vue')['Picture']
|
||||||
|
ElIconPlus: typeof import('@element-plus/icons-vue')['Plus']
|
||||||
ElImage: typeof import('element-plus/es')['ElImage']
|
ElImage: typeof import('element-plus/es')['ElImage']
|
||||||
|
ElImageViewer: typeof import('element-plus/es')['ElImageViewer']
|
||||||
ElInput: typeof import('element-plus/es')['ElInput']
|
ElInput: typeof import('element-plus/es')['ElInput']
|
||||||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
||||||
ElMain: typeof import('element-plus/es')['ElMain']
|
ElMain: typeof import('element-plus/es')['ElMain']
|
||||||
|
|
@ -87,8 +90,12 @@ declare global {
|
||||||
const ElHeader: typeof import('element-plus/es')['ElHeader']
|
const ElHeader: typeof import('element-plus/es')['ElHeader']
|
||||||
const ElIcon: typeof import('element-plus/es')['ElIcon']
|
const ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||||
const ElIconCircleClose: typeof import('@element-plus/icons-vue')['CircleClose']
|
const ElIconCircleClose: typeof import('@element-plus/icons-vue')['CircleClose']
|
||||||
|
const ElIconCirclePlus: typeof import('@element-plus/icons-vue')['CirclePlus']
|
||||||
|
const ElIconDelete: typeof import('@element-plus/icons-vue')['Delete']
|
||||||
const ElIconPicture: typeof import('@element-plus/icons-vue')['Picture']
|
const ElIconPicture: typeof import('@element-plus/icons-vue')['Picture']
|
||||||
|
const ElIconPlus: typeof import('@element-plus/icons-vue')['Plus']
|
||||||
const ElImage: typeof import('element-plus/es')['ElImage']
|
const ElImage: typeof import('element-plus/es')['ElImage']
|
||||||
|
const ElImageViewer: typeof import('element-plus/es')['ElImageViewer']
|
||||||
const ElInput: typeof import('element-plus/es')['ElInput']
|
const ElInput: typeof import('element-plus/es')['ElInput']
|
||||||
const ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
const ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
||||||
const ElMain: typeof import('element-plus/es')['ElMain']
|
const ElMain: typeof import('element-plus/es')['ElMain']
|
||||||
|
|
|
||||||
|
|
@ -91,11 +91,10 @@ defineExpose({
|
||||||
<ElFormItem prop="avatar">
|
<ElFormItem prop="avatar">
|
||||||
<Uploader
|
<Uploader
|
||||||
v-model:file="userInfoForm.avatar"
|
v-model:file="userInfoForm.avatar"
|
||||||
:limit="1"
|
:upload-props="{
|
||||||
:multiple="true"
|
accept: 'image/*',
|
||||||
accept="image/*"
|
listType:'picture'
|
||||||
class="avatar-uploader"
|
}">
|
||||||
list-type="picture">
|
|
||||||
<ElButton>点击上传头像</ElButton>
|
<ElButton>点击上传头像</ElButton>
|
||||||
</Uploader>
|
</Uploader>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
@ -116,10 +115,11 @@ defineExpose({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-uploader {
|
|
||||||
|
:deep(.a-uploader) {
|
||||||
width 100%;
|
width 100%;
|
||||||
|
|
||||||
:deep(.el-upload) {
|
.el-upload {
|
||||||
width 100%;
|
width 100%;
|
||||||
|
|
||||||
& > button {
|
& > button {
|
||||||
|
|
|
||||||
|
|
@ -5,25 +5,46 @@
|
||||||
:left-tools="leftTools"
|
:left-tools="leftTools"
|
||||||
:paging="paging">
|
:paging="paging">
|
||||||
<template #searchFormItem="{ searchForm }">
|
<template #searchFormItem="{ searchForm }">
|
||||||
|
<ElFormItem label="业务类型">
|
||||||
|
<ElSelect v-model="searchForm.bizType" clearable placeholder="业务类型" @change="research">
|
||||||
|
<ElOption v-for="item in bizList" :key="item.value" :label="item.label" :value="item.value"/>
|
||||||
|
</ElSelect>
|
||||||
|
</ElFormItem>
|
||||||
<ElFormItem label="分类名称">
|
<ElFormItem label="分类名称">
|
||||||
<ElInput v-model="searchForm.categoryName" placeholder="分类名称"/>
|
<ElInput v-model="searchForm.categoryName" clearable placeholder="分类名称" @clear="research"/>
|
||||||
|
</ElFormItem>
|
||||||
|
<ElFormItem label="创建时间">
|
||||||
|
<ElDatePicker
|
||||||
|
v-model="searchForm.createTimes"
|
||||||
|
:default-time="createTimeDefaultTime"
|
||||||
|
:shortcuts="shortcuts"
|
||||||
|
clearable
|
||||||
|
end-placeholder="结束时间"
|
||||||
|
start-placeholder="开始时间"
|
||||||
|
type="datetimerange"
|
||||||
|
@change="research"
|
||||||
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</template>
|
</template>
|
||||||
<template #simpleSearchFormItem="{ searchForm }">
|
<template #simpleSearchFormItem="{ searchForm }">
|
||||||
|
<ElFormItem style="min-width: 200px">
|
||||||
|
<ElSelect v-model="searchForm.bizType" clearable placeholder="业务类型" @change="research">
|
||||||
|
<ElOption v-for="item in bizList" :key="item.value" :label="item.label" :value="item.value"/>
|
||||||
|
</ElSelect>
|
||||||
|
</ElFormItem>
|
||||||
<ElFormItem>
|
<ElFormItem>
|
||||||
<ElInput v-model="searchForm.categoryName" clearable placeholder="分类名称" @clear="research"/>
|
<ElInput v-model="searchForm.categoryName" clearable placeholder="分类名称" @clear="research"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</template>
|
</template>
|
||||||
<template #columns>
|
<template #columns>
|
||||||
<ElTableColumn label="业务类型" prop="bizTypeName"/>
|
|
||||||
<ElTableColumn label="分类名称" prop="categoryName"/>
|
|
||||||
<ElTableColumn label="图片" prop="picture">
|
<ElTableColumn label="图片" prop="picture">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-image :preview-src-list="[AppApi.fileUrl(row.picture)]" :src="AppApi.fileUrl(row.picture)" preview-teleported show-progress style="width: 60px; height: 60px"/>
|
<el-image :preview-src-list="[AppApi.fileUrl(row.picture)]" :src="AppApi.fileUrl(row.picture)" preview-teleported show-progress style="width: 32px; height: 32px"/>
|
||||||
</template>
|
</template>
|
||||||
</ElTableColumn>
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="业务类型" prop="bizTypeTxt"/>
|
||||||
|
<ElTableColumn label="分类名称" prop="categoryName"/>
|
||||||
<ElTableColumn label="创建时间" prop="createTime"/>
|
<ElTableColumn label="创建时间" prop="createTime"/>
|
||||||
<ElTableColumn label="修改时间" prop="modifyTime"/>
|
|
||||||
</template>
|
</template>
|
||||||
<GoodsCategoryForm ref="goodsCategoryForm" @edit-succ="research"/>
|
<GoodsCategoryForm ref="goodsCategoryForm" @edit-succ="research"/>
|
||||||
</FormPage>
|
</FormPage>
|
||||||
|
|
@ -38,9 +59,60 @@ import FormPage, {
|
||||||
type ActionColumnType,
|
type ActionColumnType,
|
||||||
type ToolType,
|
type ToolType,
|
||||||
} from '@/components/page/FormPage.vue'
|
} from '@/components/page/FormPage.vue'
|
||||||
|
import Times from '@/common/utils/times.ts'
|
||||||
|
|
||||||
const goodsCategoryFormIns = useTemplateRef<InstanceType<typeof GoodsCategoryForm>>('goodsCategoryForm')
|
const goodsCategoryFormIns = useTemplateRef<InstanceType<typeof GoodsCategoryForm>>('goodsCategoryForm')
|
||||||
const formPageIns = useTemplateRef<ComponentExposed<typeof FormPage>>('formPage')
|
const formPageIns = useTemplateRef<ComponentExposed<typeof FormPage>>('formPage')
|
||||||
|
const createTimeDefaultTime: [ Date, Date ] = [
|
||||||
|
Times.toDate(Times.beginOfDay()),
|
||||||
|
Times.toDate(Times.endOfDay()),
|
||||||
|
]
|
||||||
|
const bizList = [
|
||||||
|
{
|
||||||
|
value: 'ZaiShengPin',
|
||||||
|
label: '再生品',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'HuiShouPin',
|
||||||
|
label: '回收品',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'QiTa',
|
||||||
|
label: '其他',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const shortcuts = [
|
||||||
|
{
|
||||||
|
text: '今天',
|
||||||
|
value: () => [ Times.toDate(Times.beginOfDay()), Times.toDate(Times.endOfDay()) ],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '昨天',
|
||||||
|
value: () => {
|
||||||
|
const time = Times.now().minus({day: 1})
|
||||||
|
return [ Times.toDate(Times.beginOfDay(time)), Times.toDate(Times.endOfDay(time)) ]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '本周',
|
||||||
|
value: () => {
|
||||||
|
return [ Times.toDate(Times.beginOfWeek()), Times.toDate(Times.endOfWeek()) ]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '本月',
|
||||||
|
value: () => {
|
||||||
|
return [ Times.toDate(Times.beginOfMonth()), Times.toDate(Times.endOfMonth()) ]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '今年',
|
||||||
|
value: () => {
|
||||||
|
return [ Times.toDate(Times.beginOfYear()), Times.toDate(Times.endOfYear()) ]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
const leftTools: ToolType[] = [
|
const leftTools: ToolType[] = [
|
||||||
{
|
{
|
||||||
icon: 'Plus',
|
icon: 'Plus',
|
||||||
|
|
@ -83,6 +155,11 @@ function research() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function paging(param: GoodsCategoryTypes.SearchGoodsCategoryParam) {
|
function paging(param: GoodsCategoryTypes.SearchGoodsCategoryParam) {
|
||||||
return GoodsCategoryApi.paging(param)
|
return GoodsCategoryApi.paging({
|
||||||
|
bizType: param.bizType,
|
||||||
|
categoryName: param.categoryName,
|
||||||
|
createTimeStart: param.createTimes?.[0] ? Times.format(param.createTimes[0]) : undefined,
|
||||||
|
createTimeEnd: param.createTimes?.[1] ? Times.format(param.createTimes[1]) : undefined,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -14,116 +14,120 @@
|
||||||
<ElInput v-model="formData.categoryName" :disabled="status === 'view'" placeholder="分类名称"/>
|
<ElInput v-model="formData.categoryName" :disabled="status === 'view'" placeholder="分类名称"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElFormItem label-width="90" label="图片" prop="picture">
|
<ElFormItem label-width="90" label="图片" prop="picture">
|
||||||
<!-- <ElInput
|
<Uploader
|
||||||
v-model="formData.picture"
|
ref="uploader"
|
||||||
:disabled="status === 'view'"
|
v-model:file="formData.picture"
|
||||||
placeholder="图片"/> -->
|
:upload-props="{
|
||||||
<Uploader v-model:file="formData.picture" :limit="1" :multiple="true" accept="image/*" class="avatar-uploader" list-type="picture-card">
|
accept: 'image/*',
|
||||||
<span style="font-size: 50px; padding: 0 40px">+</span>
|
listType:'picture-card',
|
||||||
|
drag:false
|
||||||
<!-- <ElButton>点击上传图片</ElButton> -->
|
}"/>
|
||||||
</Uploader>
|
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElFormItem label-width="90" label="排序" prop="sort">
|
<ElFormItem label-width="90" label="排序" prop="sort">
|
||||||
<ElInput v-model="formData.sort" :disabled="status === 'view'" placeholder="排序"/>
|
<ElInput v-model="formData.sort" :disabled="status === 'view'" placeholder="排序"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElForm>
|
</ElForm>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<ElButton @click="showDialog = false">{{ status === "view" ? "关闭" : "取消" }}</ElButton>
|
<ElButton @click="showDialog = false">{{ status === 'view' ? '关闭' : '取消' }}</ElButton>
|
||||||
<ElButton v-if="status !== 'view'" :loading="submiting" type="primary" @click="submitHandler">提交</ElButton>
|
<ElButton v-if="status !== 'view'" :loading="submiting" type="primary" @click="submitHandler">提交</ElButton>
|
||||||
</template>
|
</template>
|
||||||
</ElDialog>
|
</ElDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import GoodsCategoryApi from "@/pages/gds/goods-category/goods-category-api.ts";
|
import GoodsCategoryApi from '@/pages/gds/goods-category/goods-category-api.ts'
|
||||||
import Strings from "@/common/utils/strings.ts";
|
import Strings from '@/common/utils/strings.ts'
|
||||||
import FormUtil from "@/common/utils/formUtil.ts";
|
import FormUtil from '@/common/utils/formUtil.ts'
|
||||||
import Uploader from "@/components/uploader/Uploader.vue";
|
import Uploader from '@/components/uploader/Uploader.vue'
|
||||||
|
|
||||||
import Utils from "@/common/utils";
|
import Utils from '@/common/utils'
|
||||||
import { ElMessage, type FormInstance, type FormRules } from "element-plus";
|
import {
|
||||||
|
ElMessage,
|
||||||
|
type FormInstance,
|
||||||
|
type FormRules,
|
||||||
|
} from 'element-plus'
|
||||||
|
|
||||||
const emits = defineEmits(["editSucc"]);
|
const emits = defineEmits([ 'editSucc' ])
|
||||||
const showDialog = ref(false);
|
const showDialog = ref(false)
|
||||||
const submiting = ref(false);
|
const submiting = ref(false)
|
||||||
const status = ref<"add" | "view" | "modify">("add");
|
const status = ref<'add' | 'view' | 'modify'>('add')
|
||||||
|
|
||||||
const goodsCategoryFormIns = useTemplateRef<FormInstance>("goodsCategoryForm");
|
const goodsCategoryFormIns = useTemplateRef<FormInstance>('goodsCategoryForm')
|
||||||
|
const uploaderIns = useTemplateRef<InstanceType<typeof Uploader>>('uploader')
|
||||||
|
|
||||||
const bizList = [
|
const bizList = [
|
||||||
{
|
{
|
||||||
value: "ZaiShengPin",
|
value: 'ZaiShengPin',
|
||||||
label: "再生品",
|
label: '再生品',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "HuiShouPin",
|
value: 'HuiShouPin',
|
||||||
label: "回收品",
|
label: '回收品',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "QiTa",
|
value: 'QiTa',
|
||||||
label: "其他",
|
label: '其他',
|
||||||
},
|
},
|
||||||
];
|
]
|
||||||
|
|
||||||
const formData = Utils.resetAble(reactive<any>({}));
|
const formData = Utils.resetAble(reactive<any>({}))
|
||||||
const rules = reactive<FormRules<GoodsCategoryTypes.SearchGoodsCategoryResult>>({
|
const rules = reactive<FormRules<GoodsCategoryTypes.SearchGoodsCategoryResult>>({
|
||||||
id: [{ required: true, message: "请填写Id", trigger: "blur" }],
|
bizType: [ {required: true, message: '请填写业务类型', trigger: 'blur'} ],
|
||||||
bizType: [{ required: true, message: "请填写业务类型", trigger: "blur" }],
|
categoryName: [ {required: true, message: '请填写分类名称', trigger: 'blur'} ],
|
||||||
categoryName: [{ required: true, message: "请填写分类名称", trigger: "blur" }],
|
picture: [ {required: true, message: '请填写图片', trigger: 'blur'} ],
|
||||||
picture: [{ required: true, message: "请填写图片", trigger: "blur" }],
|
sort: [ {required: true, message: '请填写排序', trigger: 'blur'} ],
|
||||||
sort: [{ required: true, message: "请填写排序", trigger: "blur" }],
|
creatorId: [ {required: true, message: '请填写创建人 Id;sys_user.id', trigger: 'blur'} ],
|
||||||
creatorId: [{ required: true, message: "请填写创建人 Id;sys_user.id", trigger: "blur" }],
|
modifierId: [ {required: true, message: '请填写修改人 Id;sys_user.id', trigger: 'blur'} ],
|
||||||
modifierId: [{ required: true, message: "请填写修改人 Id;sys_user.id", trigger: "blur" }],
|
createTime: [ {required: true, message: '请填写创建时间', trigger: 'blur'} ],
|
||||||
createTime: [{ required: true, message: "请填写创建时间", trigger: "blur" }],
|
modifyTime: [ {required: true, message: '请填写修改时间', trigger: 'blur'} ],
|
||||||
modifyTime: [{ required: true, message: "请填写修改时间", trigger: "blur" }],
|
deleted: [ {required: true, message: '请填写是否删除; 0-->未删除、1-->已删除', trigger: 'blur'} ],
|
||||||
deleted: [{ required: true, message: "请填写是否删除; 0-->未删除、1-->已删除", trigger: "blur" }],
|
})
|
||||||
});
|
|
||||||
|
|
||||||
function dialogCloseHandler() {
|
function dialogCloseHandler() {
|
||||||
formData.$reset();
|
formData.$reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
function submitHandler() {
|
function submitHandler() {
|
||||||
if (status.value === "view") return;
|
if (status.value === 'view') return
|
||||||
submiting.value = true;
|
submiting.value = true
|
||||||
if (formData.id != null) {
|
if (formData.id != null) {
|
||||||
FormUtil.submit(goodsCategoryFormIns, () => GoodsCategoryApi.modify(formData))
|
FormUtil.submit(goodsCategoryFormIns, () => GoodsCategoryApi.modify(formData))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success("修改成功");
|
ElMessage.success('修改成功')
|
||||||
emits("editSucc");
|
emits('editSucc')
|
||||||
showDialog.value = false;
|
showDialog.value = false
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
submiting.value = false;
|
submiting.value = false
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
FormUtil.submit(goodsCategoryFormIns, () => GoodsCategoryApi.add(formData))
|
FormUtil.submit(goodsCategoryFormIns, () => GoodsCategoryApi.add(formData))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success("添加成功");
|
ElMessage.success('添加成功')
|
||||||
emits("editSucc");
|
emits('editSucc')
|
||||||
showDialog.value = false;
|
showDialog.value = false
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
submiting.value = false;
|
submiting.value = false
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
open(data: any = {}) {
|
open(data: any = {}) {
|
||||||
showDialog.value = true;
|
showDialog.value = true
|
||||||
if (!Strings.isBlank(data.id)) {
|
if (!Strings.isBlank(data.id)) {
|
||||||
status.value = "modify";
|
status.value = 'modify'
|
||||||
GoodsCategoryApi.detail(data.id!).then((res) => {
|
GoodsCategoryApi.detail(data.id!).then((res) => {
|
||||||
formData.$reset(res.data);
|
formData.$reset(res.data)
|
||||||
});
|
if (res.data.picture != null) uploaderIns.value?.setDefaultFiles([ res.data.picture ])
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
status.value = "add";
|
status.value = 'add'
|
||||||
formData.$reset(data);
|
formData.$reset(data)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
|
|
|
||||||
|
|
@ -3,26 +3,16 @@ export {}
|
||||||
declare global {
|
declare global {
|
||||||
namespace GoodsCategoryTypes {
|
namespace GoodsCategoryTypes {
|
||||||
interface SearchGoodsCategoryParam extends G.PageParam {
|
interface SearchGoodsCategoryParam extends G.PageParam {
|
||||||
// Id
|
|
||||||
id?: string
|
|
||||||
// 业务类型;字典代码:biz_type,ZaiShengPin-->再生品、HuiShouPin-->回收品、QiTa-->其他
|
// 业务类型;字典代码:biz_type,ZaiShengPin-->再生品、HuiShouPin-->回收品、QiTa-->其他
|
||||||
bizType?: string
|
bizType?: string
|
||||||
// 分类名称
|
// 分类名称
|
||||||
categoryName?: string
|
categoryName?: string
|
||||||
// 图片
|
// 创建时间范围
|
||||||
picture?: string
|
createTimes?: [ Date, Date ]
|
||||||
// 排序
|
|
||||||
sort?: number
|
|
||||||
// 创建人 Id;sys_user.id
|
|
||||||
creatorId?: string
|
|
||||||
// 修改人 Id;sys_user.id
|
|
||||||
modifierId?: string
|
|
||||||
// 创建时间
|
|
||||||
createTime?: string
|
|
||||||
// 修改时间
|
// 修改时间
|
||||||
modifyTime?: string
|
createTimeStart?: string
|
||||||
// 是否删除; 0-->未删除、1-->已删除
|
// 是否删除; 0-->未删除、1-->已删除
|
||||||
deleted?: boolean
|
createTimeEnd?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SearchGoodsCategoryResult {
|
interface SearchGoodsCategoryResult {
|
||||||
|
|
|
||||||
|
|
@ -29,21 +29,21 @@
|
||||||
</template>
|
</template>
|
||||||
<template #columns>
|
<template #columns>
|
||||||
<ElTableColumn label="商品编码" prop="sn"/>
|
<ElTableColumn label="商品编码" prop="sn"/>
|
||||||
<ElTableColumn label="产品名称" prop="goodsName"/>
|
|
||||||
<ElTableColumn label="规格" prop="specParams"/>
|
|
||||||
<ElTableColumn label="图片" width="100">
|
<ElTableColumn label="图片" width="100">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-image :preview-src-list="[AppApi.fileUrl(row.picture)]" :src="AppApi.fileUrl(row.picture)" preview-teleported show-progress style="width: 60px; height: 60px"/>
|
<el-image :preview-src-list="[AppApi.fileUrl(row.picture)]" :src="AppApi.fileUrl(row.picture)" preview-teleported show-progress style="width: 32px; height: 32px"/>
|
||||||
</template>
|
</template>
|
||||||
</ElTableColumn>
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="产品名称" prop="goodsName"/>
|
||||||
|
<ElTableColumn label="规格" prop="specParams"/>
|
||||||
|
|
||||||
<ElTableColumn label="是否可用" prop="canuse">
|
<ElTableColumn label="是否可用" prop="canuse">
|
||||||
<template #default="{row}">
|
<template #default="{row}">
|
||||||
{{ row.canuse ? '是' : '否' }}
|
<ElSwitch v-model="row.canuse" @change="enableGoodsHandler($event,row.id)"/>
|
||||||
</template>
|
</template>
|
||||||
</ElTableColumn>
|
</ElTableColumn>
|
||||||
<ElTableColumn label="备注" prop="memo"/>
|
<ElTableColumn label="备注" prop="memo"/>
|
||||||
<ElTableColumn label="创建时间" prop="createTime" width="160"/>
|
<ElTableColumn label="创建时间" prop="createTime" width="160"/>
|
||||||
<ElTableColumn label="修改时间" prop="modifyTime" width="160"/>
|
|
||||||
</template>
|
</template>
|
||||||
<GoodsForm ref="goodsForm" @edit-succ="editSuccHandler"/>
|
<GoodsForm ref="goodsForm" @edit-succ="editSuccHandler"/>
|
||||||
</FormPage>
|
</FormPage>
|
||||||
|
|
@ -106,4 +106,12 @@ const leftTools: ToolType[] = [
|
||||||
function paging(param: GoodsTypes.SearchGoodsParam) {
|
function paging(param: GoodsTypes.SearchGoodsParam) {
|
||||||
return GoodsApi.paging(param)
|
return GoodsApi.paging(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function enableGoodsHandler(enable: boolean, id: string) {
|
||||||
|
GoodsApi.enable({enable, id})
|
||||||
|
.then(() => {
|
||||||
|
ElMessage.success(enable ? '启用成功' : '禁用成功')
|
||||||
|
editSuccHandler()
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,13 @@
|
||||||
<ElInput v-model="formData.specParams" :disabled="status === 'view'" placeholder="规格"/>
|
<ElInput v-model="formData.specParams" :disabled="status === 'view'" placeholder="规格"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElFormItem label-width="90" label="图片" prop="picture">
|
<ElFormItem label-width="90" label="图片" prop="picture">
|
||||||
<Uploader v-model:file="formData.picture" :limit="1" :multiple="true" accept="image/*" class="avatar-uploader" list-type="picture-card">
|
<Uploader
|
||||||
<span style="font-size: 50px; padding: 0 40px">+</span>
|
ref="uploader"
|
||||||
</Uploader>
|
v-model:file="formData.picture"
|
||||||
|
:upload-props="{
|
||||||
|
accept: 'image/*',
|
||||||
|
listType:'picture-card'
|
||||||
|
}"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElFormItem label-width="90" label="计量单位" prop="unit">
|
<ElFormItem label-width="90" label="计量单位" prop="unit">
|
||||||
<ADict v-model="formData.unit" :disabled="status === 'view'" dict-key="unit" placeholder="计量单位" style="width: 240px"/>
|
<ADict v-model="formData.unit" :disabled="status === 'view'" dict-key="unit" placeholder="计量单位" style="width: 240px"/>
|
||||||
|
|
@ -35,7 +39,7 @@
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElForm>
|
</ElForm>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<ElButton @click="showDialog = false">{{ status === "view" ? "关闭" : "取消" }}</ElButton>
|
<ElButton @click="showDialog = false">{{ status === 'view' ? '关闭' : '取消' }}</ElButton>
|
||||||
<ElButton v-if="status !== 'view'" :loading="submiting" type="primary" @click="submitHandler">提交</ElButton>
|
<ElButton v-if="status !== 'view'" :loading="submiting" type="primary" @click="submitHandler">提交</ElButton>
|
||||||
</template>
|
</template>
|
||||||
</ElDialog>
|
</ElDialog>
|
||||||
|
|
@ -56,97 +60,99 @@ import GoodsCategoryApi from '@/pages/gds/goods-category/goods-category-api.ts'
|
||||||
import DictApi from '@/pages/sys/dict/dict-api.ts'
|
import DictApi from '@/pages/sys/dict/dict-api.ts'
|
||||||
import ADict from '@/components/a-dict/ADict.vue'
|
import ADict from '@/components/a-dict/ADict.vue'
|
||||||
|
|
||||||
const emits = defineEmits(["editSucc"]);
|
const emits = defineEmits([ 'editSucc' ])
|
||||||
const showDialog = ref(false);
|
const showDialog = ref(false)
|
||||||
const submiting = ref(false);
|
const submiting = ref(false)
|
||||||
const status = ref<"add" | "view" | "modify">("add");
|
const status = ref<'add' | 'view' | 'modify'>('add')
|
||||||
|
|
||||||
const goodsFormIns = useTemplateRef<FormInstance>("goodsForm");
|
const goodsFormIns = useTemplateRef<FormInstance>('goodsForm')
|
||||||
|
const uploaderIns = useTemplateRef<InstanceType<typeof Uploader>>('uploader')
|
||||||
|
|
||||||
const formData = Utils.resetAble(reactive<GoodsTypes.SearchGoodsResult>({ canuse: true }));
|
const formData = Utils.resetAble(reactive<GoodsTypes.SearchGoodsResult>({canuse: true}))
|
||||||
const rules = reactive<FormRules<GoodsTypes.SearchGoodsResult>>({
|
const rules = reactive<FormRules<GoodsTypes.SearchGoodsResult>>({
|
||||||
id: [{ required: true, message: "请填写Id", trigger: "blur" }],
|
id: [ {required: true, message: '请填写Id', trigger: 'blur'} ],
|
||||||
goodsCategoryId: [{ required: true, message: "请填写产品类型", trigger: "blur" }],
|
goodsCategoryId: [ {required: true, message: '请填写产品类型', trigger: 'blur'} ],
|
||||||
sn: [{ required: true, message: "请填写商品编码", trigger: "blur" }],
|
sn: [ {required: true, message: '请填写商品编码', trigger: 'blur'} ],
|
||||||
goodsName: [{ required: true, message: "请填写产品名称", trigger: "blur" }],
|
goodsName: [ {required: true, message: '请填写产品名称', trigger: 'blur'} ],
|
||||||
specParams: [{ required: true, message: "请填写规格", trigger: "blur" }],
|
specParams: [ {required: true, message: '请填写规格', trigger: 'blur'} ],
|
||||||
picture: [{ required: true, message: "请填写图片", trigger: "blur" }],
|
picture: [ {required: true, message: '请填写图片', trigger: 'blur'} ],
|
||||||
unit: [{ required: true, message: "请填写计量单位", trigger: "blur" }],
|
unit: [ {required: true, message: '请填写计量单位', trigger: 'blur'} ],
|
||||||
sort: [{ required: true, message: "请填写排序", trigger: "blur" }],
|
sort: [ {required: true, message: '请填写排序', trigger: 'blur'} ],
|
||||||
});
|
})
|
||||||
|
|
||||||
function dialogCloseHandler() {
|
function dialogCloseHandler() {
|
||||||
formData.$reset();
|
formData.$reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
function submitHandler() {
|
function submitHandler() {
|
||||||
if (status.value === "view") return;
|
if (status.value === 'view') return
|
||||||
submiting.value = true;
|
submiting.value = true
|
||||||
if (formData.id != null) {
|
if (formData.id != null) {
|
||||||
FormUtil.submit(goodsFormIns, () => GoodsApi.modify(formData))
|
FormUtil.submit(goodsFormIns, () => GoodsApi.modify(formData))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success("修改成功");
|
ElMessage.success('修改成功')
|
||||||
emits("editSucc");
|
emits('editSucc')
|
||||||
showDialog.value = false;
|
showDialog.value = false
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
submiting.value = false;
|
submiting.value = false
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
FormUtil.submit(goodsFormIns, () => GoodsApi.add(formData))
|
FormUtil.submit(goodsFormIns, () => GoodsApi.add(formData))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success("添加成功");
|
ElMessage.success('添加成功')
|
||||||
emits("editSucc");
|
emits('editSucc')
|
||||||
showDialog.value = false;
|
showDialog.value = false
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
submiting.value = false;
|
submiting.value = false
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const category = ref<GoodsCategoryTypes.SearchGoodsCategoryResult[]>([]);
|
const category = ref<GoodsCategoryTypes.SearchGoodsCategoryResult[]>([])
|
||||||
const loading = ref(false);
|
const loading = ref(false)
|
||||||
const remoteMethod = (query: string) => {
|
const remoteMethod = (query: string) => {
|
||||||
console.log(query, "query");
|
console.log(query, 'query')
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
GoodsCategoryApi.paging({size: 50, categoryName: query || undefined}).then((res) => {
|
GoodsCategoryApi.paging({size: 50, categoryName: query || undefined}).then((res) => {
|
||||||
category.value = res.data.records;
|
category.value = res.data.records
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
// category.value = list.value.filter((item) => {
|
// category.value = list.value.filter((item) => {
|
||||||
// return item.label.toLowerCase().includes(query.toLowerCase())
|
// return item.label.toLowerCase().includes(query.toLowerCase())
|
||||||
// })
|
// })
|
||||||
});
|
})
|
||||||
// } else {
|
// } else {
|
||||||
// category.value = [];
|
// category.value = [];
|
||||||
// }
|
// }
|
||||||
};
|
}
|
||||||
const unitList = ref<DictItemTypes.SearchDictItemResult[]>([])
|
const unitList = ref<DictItemTypes.SearchDictItemResult[]>([])
|
||||||
const getOpt = () => {
|
const getOpt = () => {
|
||||||
let searchForm = {
|
let searchForm = {
|
||||||
dictKey: "unit",
|
dictKey: 'unit',
|
||||||
};
|
}
|
||||||
DictApi.obtainDictData(searchForm).then((res) => {
|
DictApi.obtainDictData(searchForm).then((res) => {
|
||||||
// console.log(res.data);
|
// console.log(res.data);
|
||||||
unitList.value = res.data
|
unitList.value = res.data
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
open(data: GoodsTypes.SearchGoodsResult = {}) {
|
open(data: GoodsTypes.SearchGoodsResult = {}) {
|
||||||
showDialog.value = true;
|
showDialog.value = true
|
||||||
if (!Strings.isBlank(data.id)) {
|
if (!Strings.isBlank(data.id)) {
|
||||||
status.value = "modify";
|
status.value = 'modify'
|
||||||
GoodsApi.detail(data.id!).then((res) => {
|
GoodsApi.detail(data.id!).then((res) => {
|
||||||
formData.$reset(res.data);
|
formData.$reset(res.data)
|
||||||
});
|
if (res.data.picture != null) uploaderIns.value?.setDefaultFiles([ res.data.picture ])
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
status.value = "add";
|
status.value = 'add'
|
||||||
formData.$reset(data);
|
formData.$reset(data)
|
||||||
}
|
}
|
||||||
getOpt();
|
getOpt()
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import {
|
import {
|
||||||
get,
|
get,
|
||||||
post
|
post,
|
||||||
} from '@/common/utils/http-util.ts'
|
} from '@/common/utils/http-util.ts'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -19,4 +19,7 @@ export default {
|
||||||
del(ids: string[]) {
|
del(ids: string[]) {
|
||||||
return post('/goods/del', ids)
|
return post('/goods/del', ids)
|
||||||
},
|
},
|
||||||
|
enable(param: { enable: boolean; id: string }) {
|
||||||
|
return get('/goods/enable', param)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,12 @@
|
||||||
<ElDialog v-model="showDialog" :close-on-click-modal="false" destroy-on-close width="fit-content" @close="dialogCloseHandler">
|
<ElDialog v-model="showDialog" :close-on-click-modal="false" destroy-on-close width="fit-content" @close="dialogCloseHandler">
|
||||||
<ElForm :model="formData" :rules="rules" ref="transForm" class="form-panel" label-width="auto">
|
<ElForm :model="formData" :rules="rules" ref="transForm" class="form-panel" label-width="auto">
|
||||||
<ElFormItem label-width="90" label="看料照片" prop="checkPhoto">
|
<ElFormItem label-width="90" label="看料照片" prop="checkPhoto">
|
||||||
<Uploader v-model:files="formData.checkPhoto" :limit="3" :multiple="true" accept="image/*" class="avatar-uploader" list-type="picture-card">
|
<Uploader v-model:files="formData.checkPhoto"
|
||||||
<span style="font-size: 50px; padding: 0 40px">+</span>
|
:limit="3"
|
||||||
</Uploader>
|
:upload-props="{
|
||||||
|
accept: 'image/*',
|
||||||
|
listType:'picture-card'
|
||||||
|
}"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
<ElFormItem label-width="90" label="备注" prop="weight">
|
<ElFormItem label-width="90" label="备注" prop="weight">
|
||||||
|
|
@ -12,54 +15,58 @@
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElForm>
|
</ElForm>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<ElButton @click="showDialog = false">{{ status === "view" ? "关闭" : "取消" }}</ElButton>
|
<ElButton @click="showDialog = false">{{ status === 'view' ? '关闭' : '取消' }}</ElButton>
|
||||||
<ElButton v-if="status !== 'view'" :loading="submiting" type="primary" @click="submitHandler">提交</ElButton>
|
<ElButton v-if="status !== 'view'" :loading="submiting" type="primary" @click="submitHandler">提交</ElButton>
|
||||||
</template>
|
</template>
|
||||||
</ElDialog>
|
</ElDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import TransApi from "@/pages/order/trans-order/trans-api.ts";
|
import TransApi from '@/pages/order/trans-order/trans-api.ts'
|
||||||
// import Strings from "@/common/utils/strings.ts";
|
// import Strings from "@/common/utils/strings.ts";
|
||||||
import FormUtil from "@/common/utils/formUtil.ts";
|
import FormUtil from '@/common/utils/formUtil.ts'
|
||||||
import Utils from "@/common/utils";
|
import Utils from '@/common/utils'
|
||||||
import { ElMessage, type FormInstance, type FormRules } from "element-plus";
|
import {
|
||||||
import Uploader from "@/components/uploader/Uploader.vue";
|
ElMessage,
|
||||||
|
type FormInstance,
|
||||||
|
type FormRules,
|
||||||
|
} from 'element-plus'
|
||||||
|
import Uploader from '@/components/uploader/Uploader.vue'
|
||||||
|
|
||||||
const emits = defineEmits(["editSucc"]);
|
const emits = defineEmits([ 'editSucc' ])
|
||||||
const showDialog = ref(false);
|
const showDialog = ref(false)
|
||||||
const submiting = ref(false);
|
const submiting = ref(false)
|
||||||
const status = ref<"add" | "view" | "modify">("add");
|
const status = ref<'add' | 'view' | 'modify'>('add')
|
||||||
|
|
||||||
const transFormIns = useTemplateRef<FormInstance>("transForm");
|
const transFormIns = useTemplateRef<FormInstance>('transForm')
|
||||||
|
|
||||||
const formData = Utils.resetAble(reactive<TransTypes.CheckResult>({}));
|
const formData = Utils.resetAble(reactive<TransTypes.CheckResult>({}))
|
||||||
const rules = reactive<FormRules<TransTypes.CheckResult>>({
|
const rules = reactive<FormRules<TransTypes.CheckResult>>({
|
||||||
orderTransId: [{ required: true, message: "请填写Id", trigger: "blur" }],
|
orderTransId: [ {required: true, message: '请填写Id', trigger: 'blur'} ],
|
||||||
});
|
})
|
||||||
|
|
||||||
function dialogCloseHandler() {
|
function dialogCloseHandler() {
|
||||||
formData.$reset();
|
formData.$reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
function submitHandler() {
|
function submitHandler() {
|
||||||
// console.log(formData, "formData");
|
// console.log(formData, "formData");
|
||||||
// return;
|
// return;
|
||||||
if (status.value === "view") return;
|
if (status.value === 'view') return
|
||||||
submiting.value = true;
|
submiting.value = true
|
||||||
|
|
||||||
FormUtil.submit(transFormIns, () => {
|
FormUtil.submit(transFormIns, () => {
|
||||||
let data = Object.assign({}, formData);
|
let data = Object.assign({}, formData)
|
||||||
return TransApi.check(data);
|
return TransApi.check(data)
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success("看料成功");
|
ElMessage.success('看料成功')
|
||||||
emits("editSucc");
|
emits('editSucc')
|
||||||
showDialog.value = false;
|
showDialog.value = false
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
submiting.value = false;
|
submiting.value = false
|
||||||
});
|
})
|
||||||
|
|
||||||
// if (formData.id != null) {
|
// if (formData.id != null) {
|
||||||
// FormUtil.submit(transFormIns, () => TransApi.modify(formData))
|
// FormUtil.submit(transFormIns, () => TransApi.modify(formData))
|
||||||
|
|
@ -86,10 +93,10 @@ function submitHandler() {
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
open(data: TransTypes.SearchTransResult = {}) {
|
open(data: TransTypes.SearchTransResult = {}) {
|
||||||
formData.orderTransId = data.id;
|
formData.orderTransId = data.id
|
||||||
showDialog.value = true;
|
showDialog.value = true
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
|
|
|
||||||
|
|
@ -8,70 +8,78 @@
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
<ElFormItem label-width="90" label="车头照" prop="cargoPhoto">
|
<ElFormItem label-width="90" label="车头照" prop="cargoPhoto">
|
||||||
<Uploader v-model:file="formData.cargoPhoto" :limit="1" :multiple="true" accept="image/*" class="avatar-uploader" list-type="picture-card">
|
<Uploader v-model:file="formData.cargoPhoto"
|
||||||
<span style="font-size: 50px; padding: 0 40px">+</span>
|
:upload-props="{
|
||||||
</Uploader>
|
accept: 'image/*',
|
||||||
|
listType:'picture-card'
|
||||||
|
}"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
<ElFormItem label-width="90" label="车斗照" prop="bodyPhoto">
|
<ElFormItem label-width="90" label="车斗照" prop="bodyPhoto">
|
||||||
<Uploader v-model:file="formData.bodyPhoto" :limit="1" :multiple="true" accept="image/*" class="avatar-uploader" list-type="picture-card">
|
<Uploader v-model:file="formData.bodyPhoto"
|
||||||
<span style="font-size: 50px; padding: 0 40px">+</span>
|
:upload-props="{
|
||||||
</Uploader>
|
accept: 'image/*',
|
||||||
|
listType:'picture-card'
|
||||||
|
}"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElForm>
|
</ElForm>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<ElButton @click="showDialog = false">{{ status === "view" ? "关闭" : "取消" }}</ElButton>
|
<ElButton @click="showDialog = false">{{ status === 'view' ? '关闭' : '取消' }}</ElButton>
|
||||||
<ElButton v-if="status !== 'view'" :loading="submiting" type="primary" @click="submitHandler">提交</ElButton>
|
<ElButton v-if="status !== 'view'" :loading="submiting" type="primary" @click="submitHandler">提交</ElButton>
|
||||||
</template>
|
</template>
|
||||||
</ElDialog>
|
</ElDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import TransApi from "@/pages/order/trans-order/trans-api.ts";
|
import TransApi from '@/pages/order/trans-order/trans-api.ts'
|
||||||
// import Strings from "@/common/utils/strings.ts";
|
// import Strings from "@/common/utils/strings.ts";
|
||||||
import FormUtil from "@/common/utils/formUtil.ts";
|
import FormUtil from '@/common/utils/formUtil.ts'
|
||||||
import Utils from "@/common/utils";
|
import Utils from '@/common/utils'
|
||||||
import { ElMessage, type FormInstance, type FormRules } from "element-plus";
|
import {
|
||||||
import Uploader from "@/components/uploader/Uploader.vue";
|
ElMessage,
|
||||||
|
type FormInstance,
|
||||||
|
type FormRules,
|
||||||
|
} from 'element-plus'
|
||||||
|
import Uploader from '@/components/uploader/Uploader.vue'
|
||||||
|
|
||||||
const emits = defineEmits(["editSucc"]);
|
const emits = defineEmits([ 'editSucc' ])
|
||||||
const showDialog = ref(false);
|
const showDialog = ref(false)
|
||||||
const submiting = ref(false);
|
const submiting = ref(false)
|
||||||
const status = ref<"add" | "view" | "modify">("add");
|
const status = ref<'add' | 'view' | 'modify'>('add')
|
||||||
|
|
||||||
const transFormIns = useTemplateRef<FormInstance>("transForm");
|
const transFormIns = useTemplateRef<FormInstance>('transForm')
|
||||||
|
|
||||||
const formData = Utils.resetAble(reactive<TransTypes.InOutResult>({
|
const formData = Utils.resetAble(reactive<TransTypes.InOutResult>({
|
||||||
weight:0
|
weight: 0,
|
||||||
}));
|
}))
|
||||||
const rules = reactive<FormRules<TransTypes.InOutResult>>({
|
const rules = reactive<FormRules<TransTypes.InOutResult>>({
|
||||||
orderTransId: [{ required: true, message: "请填写Id", trigger: "blur" }],
|
orderTransId: [ {required: true, message: '请填写Id', trigger: 'blur'} ],
|
||||||
cargoPhoto: [{ required: true, message: "请上传车头照", trigger: "blur" }],
|
cargoPhoto: [ {required: true, message: '请上传车头照', trigger: 'blur'} ],
|
||||||
bodyPhoto: [{ required: true, message: "请上传车尾照", trigger: "blur" }],
|
bodyPhoto: [ {required: true, message: '请上传车尾照', trigger: 'blur'} ],
|
||||||
weight: [{ required: true, message: "请输入磅重", trigger: "blur" }],
|
weight: [ {required: true, message: '请输入磅重', trigger: 'blur'} ],
|
||||||
});
|
})
|
||||||
|
|
||||||
function dialogCloseHandler() {
|
function dialogCloseHandler() {
|
||||||
formData.$reset();
|
formData.$reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
function submitHandler() {
|
function submitHandler() {
|
||||||
if (status.value === "view") return;
|
if (status.value === 'view') return
|
||||||
submiting.value = true;
|
submiting.value = true
|
||||||
|
|
||||||
FormUtil.submit(transFormIns, () => {
|
FormUtil.submit(transFormIns, () => {
|
||||||
let data = Object.assign({}, formData);
|
let data = Object.assign({}, formData)
|
||||||
data.weight = data.weight * 1000;
|
data.weight = data.weight * 1000
|
||||||
return TransApi.coming(data);
|
return TransApi.coming(data)
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success("进场成功");
|
ElMessage.success('进场成功')
|
||||||
emits("editSucc");
|
emits('editSucc')
|
||||||
showDialog.value = false;
|
showDialog.value = false
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
submiting.value = false;
|
submiting.value = false
|
||||||
});
|
})
|
||||||
|
|
||||||
// if (formData.id != null) {
|
// if (formData.id != null) {
|
||||||
// FormUtil.submit(transFormIns, () => TransApi.modify(formData))
|
// FormUtil.submit(transFormIns, () => TransApi.modify(formData))
|
||||||
|
|
@ -98,10 +106,10 @@ function submitHandler() {
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
open(data: TransTypes.SearchTransResult = {}) {
|
open(data: TransTypes.SearchTransResult = {}) {
|
||||||
formData.orderTransId = data.id;
|
formData.orderTransId = data.id
|
||||||
showDialog.value = true;
|
showDialog.value = true
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,19 @@
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
<ElFormItem label-width="90" label="车头照" prop="cargoPhoto">
|
<ElFormItem label-width="90" label="车头照" prop="cargoPhoto">
|
||||||
<Uploader v-model:file="formData.cargoPhoto" :limit="1" :multiple="true" accept="image/*" class="avatar-uploader" list-type="picture-card">
|
<Uploader v-model:file="formData.cargoPhoto"
|
||||||
<span style="font-size: 50px; padding: 0 40px">+</span>
|
:upload-props="{
|
||||||
</Uploader>
|
accept: 'image/*',
|
||||||
|
listType:'picture-card'
|
||||||
|
}"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
<ElFormItem label-width="90" label="车斗照" prop="bodyPhoto">
|
<ElFormItem label-width="90" label="车斗照" prop="bodyPhoto">
|
||||||
<Uploader v-model:file="formData.bodyPhoto" :limit="1" :multiple="true" accept="image/*" class="avatar-uploader" list-type="picture-card">
|
<Uploader v-model:file="formData.bodyPhoto"
|
||||||
<span style="font-size: 50px; padding: 0 40px">+</span>
|
:upload-props="{
|
||||||
</Uploader>
|
accept: 'image/*',
|
||||||
|
listType:'picture-card'
|
||||||
|
}"/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElForm>
|
</ElForm>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
|
@ -27,12 +31,16 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import TransApi from "@/pages/order/trans-order/trans-api.ts";
|
import TransApi from '@/pages/order/trans-order/trans-api.ts'
|
||||||
// import Strings from "@/common/utils/strings.ts";
|
// import Strings from "@/common/utils/strings.ts";
|
||||||
import FormUtil from "@/common/utils/formUtil.ts";
|
import FormUtil from '@/common/utils/formUtil.ts'
|
||||||
import Utils from "@/common/utils";
|
import Utils from '@/common/utils'
|
||||||
import { ElMessage, type FormInstance, type FormRules } from "element-plus";
|
import {
|
||||||
import Uploader from "@/components/uploader/Uploader.vue";
|
ElMessage,
|
||||||
|
type FormInstance,
|
||||||
|
type FormRules,
|
||||||
|
} from 'element-plus'
|
||||||
|
import Uploader from '@/components/uploader/Uploader.vue'
|
||||||
|
|
||||||
const emits = defineEmits(["editSucc"]);
|
const emits = defineEmits(["editSucc"]);
|
||||||
const showDialog = ref(false);
|
const showDialog = ref(false);
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,10 @@
|
||||||
<Uploader
|
<Uploader
|
||||||
v-model:file="userFormData.avatar"
|
v-model:file="userFormData.avatar"
|
||||||
:disabled="status === 'view'"
|
:disabled="status === 'view'"
|
||||||
:limit="1"
|
:upload-props="{
|
||||||
:multiple="true"
|
accept: 'image/*',
|
||||||
accept="image/*"
|
listType:'picture'
|
||||||
class="avatar-uploader"
|
}">
|
||||||
list-type="picture">
|
|
||||||
<ElButton>点击上传头像</ElButton>
|
<ElButton>点击上传头像</ElButton>
|
||||||
</Uploader>
|
</Uploader>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue