!1 merge: upload和城市选择的重构

Merge pull request !1 from Zweihander/yx-dev-from-feature-project
This commit is contained in:
Zweihander 2024-07-09 08:56:52 +00:00 committed by Gitee
commit 5b7487eb4f
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 98 additions and 74 deletions

View File

@ -58,7 +58,7 @@
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
import type { UploadInstance, UploadProps, UploadRawFile, UploadUserFile } from 'element-plus' import type { UploadInstance, UploadProps, UploadRawFile, UploadUserFile } from 'element-plus'
import { isString } from '@/utils/is' import { isString } from '@/utils/is'
import { useUpload } from '@/components/UploadFile/src/useUpload' import { useUpload, ResponseFile } from '@/components/UploadFile/src/useUpload'
import { UploadFile } from 'element-plus/es/components/upload/src/upload' import { UploadFile } from 'element-plus/es/components/upload/src/upload'
defineOptions({ name: 'UploadFile' }) defineOptions({ name: 'UploadFile' })
@ -67,7 +67,7 @@ const message = useMessage() // 消息弹窗
const emit = defineEmits(['update:modelValue']) const emit = defineEmits(['update:modelValue'])
const props = defineProps({ const props = defineProps({
modelValue: propTypes.oneOfType<string | string[]>([String, Array<String>]).isRequired, modelValue: propTypes.oneOfType<ResponseFile[]>([]).isRequired,
fileType: propTypes.array.def(['doc', 'xls', 'ppt', 'txt', 'pdf']), // , ['png', 'jpg', 'jpeg'] fileType: propTypes.array.def(['doc', 'xls', 'ppt', 'txt', 'pdf']), // , ['png', 'jpg', 'jpeg']
fileSize: propTypes.number.def(5), // (MB) fileSize: propTypes.number.def(5), // (MB)
limit: propTypes.number.def(5), // limit: propTypes.number.def(5), //
@ -121,7 +121,7 @@ const handleFileSuccess: UploadProps['onSuccess'] = (res: any): void => {
// //
const index = fileList.value.findIndex((item) => item.response?.data === res.data) const index = fileList.value.findIndex((item) => item.response?.data === res.data)
fileList.value.splice(index, 1) fileList.value.splice(index, 1)
uploadList.value.push({ name: res.data, url: res.data }) uploadList.value.push({ name: res.data.name ?? res.data.url, url: res.data.url })
if (uploadList.value.length == uploadNumber.value) { if (uploadList.value.length == uploadNumber.value) {
fileList.value.push(...uploadList.value) fileList.value.push(...uploadList.value)
uploadList.value = [] uploadList.value = []
@ -152,35 +152,23 @@ const handlePreview: UploadProps['onPreview'] = (uploadFile) => {
// //
watch( watch(
() => props.modelValue, () => props.modelValue,
(val: string | string[]) => { (val: ResponseFile[]) => {
if (!val) { if (!val) {
fileList.value = [] // fix fileList.value = [] // fix
return return
} }
fileList.value = [] // fileList.value = val.map(({ name, url }) => ({
// 1 name: name ?? url.substring(url.lastIndexOf('/') + 1),
if (isString(val)) { url
fileList.value.push( }))
...val.split(',').map((url) => ({ name: url.substring(url.lastIndexOf('/') + 1), url }))
)
return
}
// 2
fileList.value.push(
...(val as string[]).map((url) => ({ name: url.substring(url.lastIndexOf('/') + 1), url }))
)
}, },
{ immediate: true, deep: true } { immediate: true, deep: true }
) )
// //
const emitUpdateModelValue = () => { const emitUpdateModelValue = () => {
// 1 const result = fileList.value.map(({ name, url }) => ({ name, url }))
let result: string | string[] = fileList.value.map((file) => file.url!)
// 2
if (props.limit === 1 || isString(props.modelValue)) {
result = result.join(',')
}
emit('update:modelValue', result) emit('update:modelValue', result)
} }
</script> </script>

View File

@ -118,7 +118,7 @@ const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
// //
const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => { const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => {
message.success('上传成功') message.success('上传成功')
emit('update:modelValue', res.data) emit('update:modelValue', res.data.url)
} }
// //

View File

@ -51,7 +51,7 @@ import type { UploadFile, UploadProps, UploadUserFile } from 'element-plus'
import { ElNotification } from 'element-plus' import { ElNotification } from 'element-plus'
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
import { useUpload } from '@/components/UploadFile/src/useUpload' import { useUpload, ResponseFile } from '@/components/UploadFile/src/useUpload'
defineOptions({ name: 'UploadImgs' }) defineOptions({ name: 'UploadImgs' })
@ -70,7 +70,7 @@ type FileTypes =
| 'image/x-icon' | 'image/x-icon'
const props = defineProps({ const props = defineProps({
modelValue: propTypes.oneOfType<string | string[]>([String, Array<String>]).isRequired, modelValue: propTypes.oneOfType<ResponseFile[]>([]).isRequired,
drag: propTypes.bool.def(true), // ==> true drag: propTypes.bool.def(true), // ==> true
disabled: propTypes.bool.def(false), // ==> false disabled: propTypes.bool.def(false), // ==> false
limit: propTypes.number.def(5), // ==> 5 limit: propTypes.number.def(5), // ==> 5
@ -111,7 +111,7 @@ const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
// //
interface UploadEmits { interface UploadEmits {
(e: 'update:modelValue', value: string[]): void (e: 'update:modelValue', value: ResponseFile[]): void
} }
const emit = defineEmits<UploadEmits>() const emit = defineEmits<UploadEmits>()
@ -120,7 +120,7 @@ const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => {
// //
const index = fileList.value.findIndex((item) => item.response?.data === res.data) const index = fileList.value.findIndex((item) => item.response?.data === res.data)
fileList.value.splice(index, 1) fileList.value.splice(index, 1)
uploadList.value.push({ name: res.data, url: res.data }) uploadList.value.push({ name: res.data.name ?? res.data.url, url: res.data.url })
if (uploadList.value.length == uploadNumber.value) { if (uploadList.value.length == uploadNumber.value) {
fileList.value.push(...uploadList.value) fileList.value.push(...uploadList.value)
uploadList.value = [] uploadList.value = []
@ -132,22 +132,22 @@ const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => {
// //
watch( watch(
() => props.modelValue, () => props.modelValue,
(val: string | string[]) => { (val: ResponseFile[]) => {
if (!val) { if (!val) {
fileList.value = [] // fix fileList.value = [] // fix
return return
} }
fileList.value = [] // fileList.value = val.map(({ name, url }) => ({
fileList.value.push( name: name ?? url.substring(url.lastIndexOf('/') + 1),
...(val as string[]).map((url) => ({ name: url.substring(url.lastIndexOf('/') + 1), url })) url
) }))
}, },
{ immediate: true, deep: true } { immediate: true, deep: true }
) )
// //
const emitUpdateModelValue = () => { const emitUpdateModelValue = () => {
let result: string[] = fileList.value.map((file) => file.url!) let result: ResponseFile[] = fileList.value.map(({ name, url }) => ({ name, url: url! }))
emit('update:modelValue', result) emit('update:modelValue', result)
} }
// //
@ -157,7 +157,7 @@ const handleRemove = (uploadFile: UploadFile) => {
) )
emit( emit(
'update:modelValue', 'update:modelValue',
fileList.value.map((file) => file.url!) fileList.value.map(({ name, url }) => ({ name, url: url! }))
) )
} }

View File

@ -3,6 +3,11 @@ import CryptoJS from 'crypto-js'
import { UploadRawFile, UploadRequestOptions } from 'element-plus/es/components/upload/src/upload' import { UploadRawFile, UploadRequestOptions } from 'element-plus/es/components/upload/src/upload'
import axios from 'axios' import axios from 'axios'
export type ResponseFile = {
name: string
url: string
}
export const useUpload = () => { export const useUpload = () => {
// 后端上传地址 // 后端上传地址
const uploadUrl = import.meta.env.VITE_UPLOAD_URL const uploadUrl = import.meta.env.VITE_UPLOAD_URL
@ -31,7 +36,7 @@ export const useUpload = () => {
// 模式二:后端上传 // 模式二:后端上传
// 重写 el-upload httpRequest 文件上传成功会走成功的钩子,失败走失败的钩子 // 重写 el-upload httpRequest 文件上传成功会走成功的钩子,失败走失败的钩子
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
FileApi.updateFile({ file: options.file }) FileApi.updateFileEx({ file: options.file })
.then((res) => { .then((res) => {
if (res.code === 0) { if (res.code === 0) {
resolve(res) resolve(res)

View File

@ -49,31 +49,39 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="省份" prop="provinceId"> <el-form-item label="省份" prop="provinceId">
<el-cascader <el-select
v-model="formData.provinceId"
:options="areaList"
:props="props1"
class="w-1/1"
clearable clearable
filterable filterable
placeholder="请选择省份" placeholder="请选择省份"
v-model="formData.provinceId"
@change="onProvinceChange"
:disabled="formType !== 'create'" :disabled="formType !== 'create'"
>
<el-option
v-for="item in areaList"
:key="item.id"
:label="item.name"
:value="item.id"
/> />
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="城市" prop="cityId"> <el-form-item label="城市" prop="cityId">
<el-cascader <el-select
v-model="formData.cityId"
:options="areaList"
:props="props1"
:show-all-levels="false"
class="w-1/1"
clearable clearable
filterable filterable
placeholder="请选择城市" placeholder="请选择城市"
v-model="formData.cityId"
:disabled="formType !== 'create'" :disabled="formType !== 'create'"
>
<el-option
v-for="item in cityList"
:key="item.id"
:label="item.name"
:value="item.id"
/> />
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -271,6 +279,7 @@ import { useUserStore } from '@/store/modules/user'
import { CustomerCompanyApi, CustomerCompanyVO } from '@/api/cms/customerCompany' import { CustomerCompanyApi, CustomerCompanyVO } from '@/api/cms/customerCompany'
import * as DeptApi from '@/api/system/dept' import * as DeptApi from '@/api/system/dept'
import {defaultProps, handleTree} from "@/utils/tree"; import {defaultProps, handleTree} from "@/utils/tree";
import { log } from 'console'
/** 项目基本信息 表单 */ /** 项目基本信息 表单 */
defineOptions({ name: 'ProjectForm' }) defineOptions({ name: 'ProjectForm' })
@ -282,6 +291,7 @@ const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // const dialogTitle = ref('') //
const formLoading = ref(false) // 12 const formLoading = ref(false) // 12
const areaList = ref([]) // const areaList = ref([]) //
const cityList = ref([]); // options
const formType = ref('') // create - update - const formType = ref('') // create - update -
const userOptions = ref<UserApi.UserVO[]>([]) // const userOptions = ref<UserApi.UserVO[]>([]) //
const customerCompanyOptions = ref<CustomerCompanyVO[]>([]) // const customerCompanyOptions = ref<CustomerCompanyVO[]>([]) //
@ -427,4 +437,10 @@ const resetForm = () => {
} }
formRef.value?.resetFields() formRef.value?.resetFields()
} }
//
const onProvinceChange = (value: number)=>{
formData.value.cityId = undefined;
cityList.value = (areaList.value.find(({id})=>id===value) as any)?.children ?? [];
}
</script> </script>

View File

@ -36,29 +36,37 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="省份" prop="provinceId"> <el-form-item label="省份" prop="provinceId">
<el-cascader <el-select
v-model="formData.provinceId"
:options="areaList"
:props="props"
class="w-1/1"
clearable clearable
filterable filterable
placeholder="请选择省份" placeholder="请选择省份"
v-model="formData.provinceId"
@change="onProvinceChange"
>
<el-option
v-for="item in areaList"
:key="item.id"
:label="item.name"
:value="item.id"
/> />
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="城市" prop="cityId"> <el-form-item label="城市" prop="cityId">
<el-cascader <el-select
v-model="formData.cityId"
:options="areaList"
:props="props"
:show-all-levels="false"
class="w-1/1"
clearable clearable
filterable filterable
placeholder="请选择城市" placeholder="请选择城市"
v-model="formData.cityId"
>
<el-option
v-for="item in cityList"
:key="item.id"
:label="item.name"
:value="item.id"
/> />
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -309,6 +317,7 @@ const formRef = ref() // 表单 Ref
const processDefineKey = 'pms_project_init' // Key const processDefineKey = 'pms_project_init' // Key
const userList = ref<any[]>([]) // const userList = ref<any[]>([]) //
const areaList = ref([]) // const areaList = ref([]) //
const cityList = ref([]); // options
const customerCompanyOptions = ref<CustomerCompanyVO[]>([]) // const customerCompanyOptions = ref<CustomerCompanyVO[]>([]) //
const deptOptions = ref<any[]>([]) // const deptOptions = ref<any[]>([]) //
@ -354,4 +363,10 @@ onMounted(async () => {
// //
customerCompanyOptions.value = await CustomerCompanyApi.getCustomerCompanyList() customerCompanyOptions.value = await CustomerCompanyApi.getCustomerCompanyList()
}) })
//
const onProvinceChange = (value: number)=>{
formData.value.cityId = undefined;
cityList.value = (areaList.value.find(({id})=>id===value) as any)?.children ?? [];
}
</script> </script>