Compare commits

2 Commits

Author SHA1 Message Date
4bd5797772 feat: 🚀 视频上传可以覆盖上传 2025-04-28 15:36:15 +08:00
927e2ebc4c feat: 🚀 banner添加相关分类 2025-04-23 17:21:46 +08:00
5 changed files with 91 additions and 42 deletions

View File

@@ -9,11 +9,13 @@
:show-file-list="false" :show-file-list="false"
:http-request="handleHttpUpload" :http-request="handleHttpUpload"
:before-upload="beforeUpload" :before-upload="beforeUpload"
:on-success="uploadSuccess"
:on-error="uploadError" :on-error="uploadError"
:on-exceed="handleExceed"
:limit="1" :limit="1"
:accept="fileType.join(',')" :accept="fileType.join(',')"
ref="upload"
> >
<!-- :on-success="uploadSuccess" -->
<!-- disabled --> <!-- disabled -->
<el-input v-model="videoShowUrl" style="width: 414px" @click.stop @input="handleInput"> <el-input v-model="videoShowUrl" style="width: 414px" @click.stop @input="handleInput">
<template #prepend <template #prepend
@@ -33,9 +35,10 @@ import { FolderAdd } from "@element-plus/icons-vue";
import { ref, computed, inject } from "vue"; import { ref, computed, inject } from "vue";
import { generateUUID } from "@/utils"; import { generateUUID } from "@/utils";
import { uploadVideo } from "@/api/modules/upload"; import { uploadVideo } from "@/api/modules/upload";
import { genFileId } from "element-plus";
import { ElNotification, formContextKey, formItemContextKey } from "element-plus"; import { ElNotification, formContextKey, formItemContextKey } from "element-plus";
import type { UploadProps, UploadRequestOptions } from "element-plus"; import type { UploadProps, UploadRawFile, UploadInstance } from "element-plus";
//UploadRequestOptions
interface UploadFileProps { interface UploadFileProps {
videoUrl: any; // 图片地址 ==> 必传 videoUrl: any; // 图片地址 ==> 必传
api?: (params: any) => Promise<any>; // 上传图片的 api 方法,一般项目上传都是同一个 api 方法,在组件里直接引入即可 ==> 非必传 api?: (params: any) => Promise<any>; // 上传图片的 api 方法,一般项目上传都是同一个 api 方法,在组件里直接引入即可 ==> 非必传
@@ -69,7 +72,7 @@ const routerName = ref(routerObj[routerValueName]);
// 生成组件唯一id // 生成组件唯一id
const uuid = ref("id-" + generateUUID()); const uuid = ref("id-" + generateUUID());
const upload = ref<UploadInstance>();
// 获取 el-form 组件上下文 // 获取 el-form 组件上下文
const formContext = inject(formContextKey, void 0); const formContext = inject(formContextKey, void 0);
// 获取 el-form-item 组件上下文 // 获取 el-form-item 组件上下文
@@ -86,23 +89,45 @@ interface UploadEmits {
(e: "update:videoUrl", value: string): void; (e: "update:videoUrl", value: string): void;
} }
const emit = defineEmits<UploadEmits>(); const emit = defineEmits<UploadEmits>();
const handleHttpUpload = async (options: UploadRequestOptions) => { const handleHttpUpload = async (options: any) => {
let formData = new FormData(); let formData = new FormData();
formData.append("video", options.file); formData.append("video", options.file);
try { try {
const api = props.api ?? uploadVideo; const api = props.api ?? uploadVideo;
const { data } = await api(formData, routerName.value); const { data } = await api(formData, routerName.value);
if (data.path) {
ElNotification({
title: "温馨提示",
message: "视频上传成功!",
type: "success"
});
emit("update:videoUrl", data.path); emit("update:videoUrl", data.path);
// 调用 el-form 内部的校验方法(可自动校验) // 调用 el-form 内部的校验方法(可自动校验)
formItemContext?.prop && formContext?.validateField([formItemContext.prop as string]); formItemContext?.prop && formContext?.validateField([formItemContext.prop as string]);
} else {
videoShowUrl.value = "";
emit("update:videoUrl", "");
}
} catch (error) { } catch (error) {
videoShowUrl.value = "";
emit("update:videoUrl", "");
if (!error) {
return;
}
options.onError(error as any); options.onError(error as any);
} }
}; };
const handleExceed: UploadProps["onExceed"] = files => {
upload.value!.clearFiles();
const file = files[0] as UploadRawFile;
file.uid = genFileId();
let options: any = {
file
};
handleHttpUpload(options);
};
const handleInput = () => { const handleInput = () => {
emit("update:videoUrl", videoShowUrl.value); emit("update:videoUrl", videoShowUrl.value);
console.log("会触发吗");
}; };
/** /**
@@ -132,13 +157,13 @@ const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
/** /**
* @description 视频上传成功 * @description 视频上传成功
* */ * */
const uploadSuccess = () => { // const uploadSuccess = () => {
ElNotification({ // ElNotification({
title: "温馨提示", // title: "温馨提示",
message: "视频上传成功!", // message: "视频上传成功!",
type: "success" // type: "success"
}); // });
}; // };
/** /**
* @description 视频上传错误 * @description 视频上传错误
@@ -153,8 +178,10 @@ const uploadError = () => {
watch( watch(
() => props.videoUrl, () => props.videoUrl,
(newVal: any) => { (newVal: any) => {
if (newVal) {
videoShowUrl.value = newVal; videoShowUrl.value = newVal;
} }
}
); );
</script> </script>

View File

@@ -159,6 +159,7 @@
show-checkbox show-checkbox
check-strictly check-strictly
@change="handleSelectChange(_ruleForm[`${item.prop}`], item.prop)" @change="handleSelectChange(_ruleForm[`${item.prop}`], item.prop)"
style="max-width: 240px"
/> />
</template> </template>
<template v-if="item.type === 'treeSelects'"> <template v-if="item.type === 'treeSelects'">

View File

@@ -78,6 +78,14 @@ export const EDIT_FORM_DATA: FormItem[] = [
label: "Banner分类: ", label: "Banner分类: ",
options: [] options: []
}, },
{
prop: "rel_prod_cate_id",
placeholder: "请选择",
type: "treeSelect",
label: "相关分类: ",
options: []
},
{ {
prop: "sort", prop: "sort",
placeholder: "请输入", placeholder: "请输入",

View File

@@ -84,6 +84,7 @@ import { messageBox } from "@/utils/messageBox";
import { useMsg } from "@/hooks/useMsg"; import { useMsg } from "@/hooks/useMsg";
import { useExport } from "@/hooks/useExport"; import { useExport } from "@/hooks/useExport";
import { integerRexg } from "@/utils/regexp/index"; import { integerRexg } from "@/utils/regexp/index";
import { getProductCategoryListApi } from "@/api/modules/productList";
// 图片地址 // 图片地址
import { h } from "@/utils/url"; import { h } from "@/utils/url";
// 列表接口 // 列表接口
@@ -131,6 +132,28 @@ const treeProps = {
label: "label", label: "label",
value: "value" value: "value"
}; };
const addLabelValue = (arr: any) => {
return arr.map((item: any) => {
// 为当前对象添加 label 和 value 属性
const newItem = { ...item };
newItem.label = newItem.name;
newItem.value = newItem.id;
// 如果有子对象,递归调用 addLabelValue 处理子对象
if (newItem.children && Array.isArray(newItem.children)) {
newItem.children = addLabelValue(newItem.children);
}
return newItem;
});
};
//产品分类(后端大佬说直接掉列表接口)
const getProductCategoryList = async () => {
const result = await getProductCategoryListApi();
if (result?.code === 0) {
let dataClone: any = cloneDeep(result?.data);
dataStore.editFormData[6].options = addLabelValue(dataClone);
}
};
const buildTree = (data: any, outerLinkTo: any = "") => { const buildTree = (data: any, outerLinkTo: any = "") => {
return data.map((item: any) => { return data.map((item: any) => {
@@ -152,24 +175,18 @@ const buildTree = (data: any, outerLinkTo: any = "") => {
}; };
// let isFirstRequest = true; // let isFirstRequest = true;
const handleRadioGroupEmits = (value: any) => { const handleRadioGroupEmits = (value: any) => {
// if (value !== "video" || value !== "image") {
// return;
// }
if (value === "video") { if (value === "video") {
dataStore.editFormData = EDIT_FORM_DATA1; dataStore.editFormData = EDIT_FORM_DATA1;
dataStore.rules = RULES1; dataStore.rules = RULES1;
getBannerClassEditList(); getBannerClassEditList();
} }
// getBannerClassList();
if (value === "image") { if (value === "image") {
dataStore.isFirstRequest = true; dataStore.isFirstRequest = true;
dataStore.editFormData = EDIT_FORM_DATA; dataStore.editFormData = EDIT_FORM_DATA;
dataStore.rules = RULES; dataStore.rules = RULES;
getBannerClassEditList(); getBannerClassEditList();
} }
// console.log(value, "==========value==========");
// getBannerClassEditList();
}; };
const getSystemUrls = async (node: any, resolve: any) => { const getSystemUrls = async (node: any, resolve: any) => {
@@ -201,7 +218,8 @@ const getSystemUrls = async (node: any, resolve: any) => {
const setImgOrVideo = () => { const setImgOrVideo = () => {
if (dataStore.editRuleForm.type === "image") { if (dataStore.editRuleForm.type === "image") {
dataStore.editFormData = EDIT_FORM_DATA; dataStore.editFormData = EDIT_FORM_DATA;
} else { }
if (dataStore.editRuleForm.type === "video") {
dataStore.editFormData = EDIT_FORM_DATA1; dataStore.editFormData = EDIT_FORM_DATA1;
} }
getBannerClassEditList(); getBannerClassEditList();
@@ -214,6 +232,7 @@ const getBannerRead = async (id: any) => {
if (result?.code === 0) { if (result?.code === 0) {
dataStore.editRuleForm = result?.data; dataStore.editRuleForm = result?.data;
setImgOrVideo(); setImgOrVideo();
getProductCategoryList();
if (dataStore.editRuleForm.link && dataStore.editRuleForm.link_to) { if (dataStore.editRuleForm.link && dataStore.editRuleForm.link_to) {
let { id, name, link } = dataStore.editRuleForm.link_echo_data; let { id, name, link } = dataStore.editRuleForm.link_echo_data;
if (!id || !name || !link) { if (!id || !name || !link) {
@@ -262,20 +281,6 @@ const getBannerUp = async () => {
dataStore.isFirstRequest = true; dataStore.isFirstRequest = true;
} }
}; };
// 分类
const getBannerClassList = async () => {
const result = await getBannerClassListApi();
if (result?.code === 0) {
let arr: any = [];
result?.data?.forEach((item: any) => {
arr.push({ value: item.id, label: item.name });
});
dataStore.formData[1].options = arr;
// dataStore.editFormData[4].options = arr;
}
};
getBannerClassList();
//详情里的分类 //详情里的分类
const getBannerClassEditList = async () => { const getBannerClassEditList = async () => {
const result = await getBannerClassListApi(); const result = await getBannerClassListApi();
@@ -284,10 +289,11 @@ const getBannerClassEditList = async () => {
result?.data?.forEach((item: any) => { result?.data?.forEach((item: any) => {
arr.push({ value: item.id, label: item.name }); arr.push({ value: item.id, label: item.name });
}); });
dataStore.formData[1].options = arr;
dataStore.editFormData[5].options = arr; dataStore.editFormData[5].options = arr;
} }
}; };
getBannerClassEditList();
// 新增 // 新增
const getBannerListSave = async () => { const getBannerListSave = async () => {
const result = await getBannerListSaveApi(dataStore.editRuleForm); const result = await getBannerListSaveApi(dataStore.editRuleForm);
@@ -343,6 +349,8 @@ const handleAdd = () => {
dataStore.title = "添加Banner"; dataStore.title = "添加Banner";
dataStore.visible = true; dataStore.visible = true;
getBannerClassEditList(); getBannerClassEditList();
// getBannerClassList();
getProductCategoryList();
}; };
// 抽屉关闭前的钩子 // 抽屉关闭前的钩子
const handleBeforeClone = () => { const handleBeforeClone = () => {

View File

@@ -26,7 +26,12 @@
</el-form-item> </el-form-item>
<el-form-item label="产品参数"> <el-form-item label="产品参数">
<el-input v-model="_ruleFormParam.params" style="width: 440px" /> <el-input
v-model="_ruleFormParam.params"
style="width: 440px"
type="textarea"
:autosize="{ minRows: 10, maxRows: 20 }"
/>
</el-form-item> </el-form-item>
<el-form-item label="产品排序" style="width: 440px" required> <el-form-item label="产品排序" style="width: 440px" required>