|
@@ -19,9 +19,11 @@
|
|
|
:type="i.itemType ? i.itemType : 'text'"
|
|
|
:placeholder="i.placeholder ? i.placeholder : '请输入'"
|
|
|
:clearable="i.clearable ? i.clearable : false"
|
|
|
+ :readonly="i.readonly != undefined ? i.readonly : false"
|
|
|
:rules="getRules(i.prop)"
|
|
|
>
|
|
|
</van-field>
|
|
|
+ <!-- switch -->
|
|
|
<van-field v-if="i.type == 'switch'" :label="i.label" :name="i.prop">
|
|
|
<template #input>
|
|
|
<van-switch v-model="formData[i.prop]" />
|
|
@@ -77,8 +79,9 @@
|
|
|
:name="i.prop"
|
|
|
v-model="formData[i.prop + 'Name']"
|
|
|
is-link
|
|
|
- readonly
|
|
|
- @click="i.showPicker = true"
|
|
|
+ :readonly="i.readonly != undefined ? i.readonly : true"
|
|
|
+ :placeholder="i.placeholder ? i.placeholder : '请选择'"
|
|
|
+ @click="() => (!formOption.readonly ? (i.showPicker = true) : '')"
|
|
|
:rules="getRules(i.prop)"
|
|
|
>
|
|
|
</van-field>
|
|
@@ -90,6 +93,9 @@
|
|
|
>
|
|
|
<van-picker
|
|
|
:columns="i.pickerOption.columns"
|
|
|
+ :columns-field-names="
|
|
|
+ i.fieldNames ? i.fieldNames : onePickerFieldNames
|
|
|
+ "
|
|
|
@cancel="i.showPicker = false"
|
|
|
@confirm="(option) => onConfirmPicker(option, i, index)"
|
|
|
/>
|
|
@@ -101,8 +107,9 @@
|
|
|
:name="i.prop"
|
|
|
v-model="formData[i.prop]"
|
|
|
is-link
|
|
|
- readonly
|
|
|
- @click="i.showPicker = true"
|
|
|
+ :readonly="i.readonly != undefined ? i.readonly : true"
|
|
|
+ :placeholder="i.placeholder ? i.placeholder : '请选择'"
|
|
|
+ @click="() => (!formOption.readonly ? (i.showPicker = true) : '')"
|
|
|
:rules="getRules(i.prop)"
|
|
|
>
|
|
|
</van-field>
|
|
@@ -127,8 +134,9 @@
|
|
|
:name="i.prop"
|
|
|
v-model="formData[i.prop + 'Name']"
|
|
|
is-link
|
|
|
- readonly
|
|
|
- @click="i.showPicker = true"
|
|
|
+ :readonly="i.readonly != undefined ? i.readonly : true"
|
|
|
+ :placeholder="i.placeholder ? i.placeholder : '请选择'"
|
|
|
+ @click="() => (!formOption.readonly ? (i.showPicker = true) : '')"
|
|
|
:rules="getRules(i.prop)"
|
|
|
/>
|
|
|
<van-popup
|
|
@@ -146,7 +154,6 @@
|
|
|
@finish="(option) => (i.finishFn ? i.finishFn(option) : () => {})"
|
|
|
/>
|
|
|
</van-popup>
|
|
|
-
|
|
|
<!-- 级联 公共 -->
|
|
|
<van-field
|
|
|
v-if="i.type == 'cascader' && i.itemType == 'common'"
|
|
@@ -154,8 +161,9 @@
|
|
|
:name="i.prop"
|
|
|
v-model="formData[i.prop + 'Name']"
|
|
|
is-link
|
|
|
- readonly
|
|
|
- @click="i.showPicker = true"
|
|
|
+ :readonly="i.readonly != undefined ? i.readonly : true"
|
|
|
+ :placeholder="i.placeholder ? i.placeholder : '请选择'"
|
|
|
+ @click="() => (!formOption.readonly ? (i.showPicker = true) : '')"
|
|
|
:rules="getRules(i.prop)"
|
|
|
/>
|
|
|
<van-popup
|
|
@@ -182,7 +190,19 @@
|
|
|
(option) => (i.finishFn ? i.finishFn(i, option) : () => {})
|
|
|
" -->
|
|
|
</van-popup>
|
|
|
-
|
|
|
+ <!-- 文件上传 -->
|
|
|
+ <van-field name="uploader" v-if="i.type == 'upload'" :label="i.label">
|
|
|
+ <template #input>
|
|
|
+ <van-uploader
|
|
|
+ v-model="formData[i.prop]"
|
|
|
+ :after-read="afterRead"
|
|
|
+ multiple
|
|
|
+ :max-count="9"
|
|
|
+ :max-size="5 * 1024 * 1024"
|
|
|
+ @oversize="onOversize"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </van-field>
|
|
|
<!-- 插槽 -->
|
|
|
<van-field v-if="i.type == 'slot'" :label="i.label">
|
|
|
<template #input>
|
|
@@ -213,6 +233,7 @@
|
|
|
:type="i.itemType ? i.itemType : 'text'"
|
|
|
:placeholder="i.placeholder ? i.placeholder : '请输入'"
|
|
|
:clearable="i.clearable ? i.clearable : false"
|
|
|
+ :readonly="i.readonly != undefined ? i.readonly : false"
|
|
|
:rules="getRules(i.prop)"
|
|
|
>
|
|
|
</van-field>
|
|
@@ -223,7 +244,8 @@
|
|
|
:name="i.prop"
|
|
|
v-model="formData[btnConfigCopy.prop][index][i.prop + 'Name']"
|
|
|
is-link
|
|
|
- readonly
|
|
|
+ :readonly="i.readonly != undefined ? i.readonly : true"
|
|
|
+ :placeholder="i.placeholder ? i.placeholder : '请选择'"
|
|
|
@click="handleListItemClick(i, index, sonIndex)"
|
|
|
:rules="getRules(i.prop)"
|
|
|
>
|
|
@@ -235,7 +257,8 @@
|
|
|
:name="i.prop"
|
|
|
v-model="formData[btnConfigCopy.prop][index][i.prop]"
|
|
|
is-link
|
|
|
- readonly
|
|
|
+ :readonly="i.readonly != undefined ? i.readonly : true"
|
|
|
+ :placeholder="i.placeholder ? i.placeholder : '请选择'"
|
|
|
@click="handleListItemClick(i, index, sonIndex)"
|
|
|
:rules="getRules(i.prop)"
|
|
|
>
|
|
@@ -252,6 +275,9 @@
|
|
|
>
|
|
|
<van-picker
|
|
|
:columns="item.pickerOption.columns"
|
|
|
+ :columns-field-names="
|
|
|
+ item.fieldNames ? item.fieldNames : onePickerFieldNames
|
|
|
+ "
|
|
|
@cancel="item.showPicker = false"
|
|
|
@confirm="(option) => onConfirmListPicker(option, item)"
|
|
|
/>
|
|
@@ -336,8 +362,13 @@ const { formConfig, formOption, rules } = toRefs(props);
|
|
|
const formData = computed(() => {
|
|
|
return proxy.modelValue;
|
|
|
});
|
|
|
-//
|
|
|
-const fieldNames = { text: "label", value: "id" };
|
|
|
+const cityOption = ref([]);
|
|
|
+const fileList = ref([]);
|
|
|
+const fieldNames = { text: "label", value: "id", children: "children" };
|
|
|
+const onePickerFieldNames = {
|
|
|
+ text: "text",
|
|
|
+ value: "value",
|
|
|
+};
|
|
|
const emit = defineEmits(["update:modelValue"]);
|
|
|
|
|
|
const onSubmit = () => {
|
|
@@ -355,9 +386,8 @@ const getReadonly = (i) => {
|
|
|
};
|
|
|
|
|
|
// 国家初始化
|
|
|
-const cityOption = ref([]);
|
|
|
const cityOptionInit = () => {
|
|
|
- proxy.post("/areaInfo/list", formData.value).then((res) => {
|
|
|
+ proxy.post("/areaInfo/list", { parentId: "0" }).then((res) => {
|
|
|
cityOption.value = res.data.map((item, index) => {
|
|
|
return {
|
|
|
...item,
|
|
@@ -369,59 +399,125 @@ const cityOptionInit = () => {
|
|
|
});
|
|
|
});
|
|
|
};
|
|
|
+const recursionFn = (arr, val, valueAtt, childrenAtt) => {
|
|
|
+ for (let i = 0; i < arr.length; i++) {
|
|
|
+ const e = arr[i];
|
|
|
+ if (e[valueAtt] !== val) {
|
|
|
+ if (e[childrenAtt] && e[childrenAtt].length > 0) {
|
|
|
+ const current = recursionFn(e.children, val, valueAtt, childrenAtt);
|
|
|
+ if (current) {
|
|
|
+ return current;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return e;
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+const selectDataEcho = (item, val) => {
|
|
|
+ if (item.type === "picker" && item.itemType === "onePicker") {
|
|
|
+ const textAtt = item.fieldNames
|
|
|
+ ? item.fieldNames.text
|
|
|
+ : onePickerFieldNames.text;
|
|
|
+ const valueAtt = item.fieldNames
|
|
|
+ ? item.fieldNames.value
|
|
|
+ : onePickerFieldNames.value;
|
|
|
+ const current = item.pickerOption.columns.find((x) => x[valueAtt] === val);
|
|
|
+ return current ? current[textAtt] : "";
|
|
|
+ } else if (item.type === "cascader" && item.itemType === "common") {
|
|
|
+ const textAtt = item.fieldNames ? item.fieldNames.text : fieldNames.text;
|
|
|
+ const valueAtt = item.fieldNames ? item.fieldNames.value : fieldNames.value;
|
|
|
+ const childrenAtt = item.fieldNames
|
|
|
+ ? item.fieldNames.children
|
|
|
+ : fieldNames.children;
|
|
|
+ const arr = item.options ? item.options : [];
|
|
|
+ const current = recursionFn(arr, val, valueAtt, childrenAtt);
|
|
|
+ return current ? current[textAtt] : "";
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
let btnConfigCopy = {};
|
|
|
const btnPickerList = ref([]);
|
|
|
-const formDataInit = () => {
|
|
|
- var map = {
|
|
|
- input: "",
|
|
|
- radio: "",
|
|
|
- switch: false,
|
|
|
- checkbox: [],
|
|
|
- date: "",
|
|
|
- picker: "",
|
|
|
- cascader: "",
|
|
|
- };
|
|
|
- // 判断是否需要按钮
|
|
|
- if (formOption.value.btnConfig && formOption.value.btnConfig.isNeed) {
|
|
|
- formData.value[formOption.value.btnConfig.prop] = [];
|
|
|
- btnConfigCopy = { ...formOption.value.btnConfig };
|
|
|
- if (
|
|
|
- formOption.value.btnConfig.listConfig &&
|
|
|
- formOption.value.btnConfig.listConfig.length > 0
|
|
|
- ) {
|
|
|
- btnPickerList.value = formOption.value.btnConfig.listConfig
|
|
|
- .filter((x) => x.type === "picker")
|
|
|
- .map((x) => x.itemType);
|
|
|
- }
|
|
|
- }
|
|
|
- for (let i = 0; i < formConfig.value.length; i++) {
|
|
|
- const element = formConfig.value[i];
|
|
|
- if (element.type === "slot") {
|
|
|
- continue;
|
|
|
- }
|
|
|
- if (element.type === "cascader" && element.itemType === "city") {
|
|
|
- cityOptionInit();
|
|
|
+const formDataInit = (flag) => {
|
|
|
+ if (!flag) {
|
|
|
+ var map = {
|
|
|
+ input: "",
|
|
|
+ radio: "",
|
|
|
+ switch: false,
|
|
|
+ checkbox: [],
|
|
|
+ date: "",
|
|
|
+ picker: "",
|
|
|
+ cascader: "",
|
|
|
+ upload: [],
|
|
|
+ };
|
|
|
+ // 判断是否需要按钮
|
|
|
+ if (formOption.value.btnConfig && formOption.value.btnConfig.isNeed) {
|
|
|
+ formData.value[formOption.value.btnConfig.prop] = [];
|
|
|
+ btnConfigCopy = { ...formOption.value.btnConfig };
|
|
|
+ if (
|
|
|
+ formOption.value.btnConfig.listConfig &&
|
|
|
+ formOption.value.btnConfig.listConfig.length > 0
|
|
|
+ ) {
|
|
|
+ btnPickerList.value = formOption.value.btnConfig.listConfig
|
|
|
+ .filter((x) => x.type === "picker")
|
|
|
+ .map((x) => x.itemType);
|
|
|
+ }
|
|
|
}
|
|
|
- if (element.type === "picker" || element.type === "cascader") {
|
|
|
- formData.value[element.prop] = map[element.type];
|
|
|
- formData.value[element.prop + "Name"] = map[element.type];
|
|
|
+ // 初始化默认值
|
|
|
+ for (let i = 0; i < formConfig.value.length; i++) {
|
|
|
+ const element = formConfig.value[i];
|
|
|
+ if (
|
|
|
+ formData.value[element.prop] === undefined ||
|
|
|
+ formData.value[element.prop] === ""
|
|
|
+ ) {
|
|
|
+ if (element.type === "slot") {
|
|
|
+ continue;
|
|
|
+ } else if (element.type === "cascader" && element.itemType === "city") {
|
|
|
+ cityOptionInit();
|
|
|
+ formData.value[element.prop] = map[element.type];
|
|
|
+ formData.value[element.prop + "Name"] = map[element.type];
|
|
|
+ } else if (element.type === "picker" || element.type === "cascader") {
|
|
|
+ formData.value[element.prop] = map[element.type];
|
|
|
+ formData.value[element.prop + "Name"] = map[element.type];
|
|
|
+ } else if (map[element.type] != undefined) {
|
|
|
+ formData.value[element.prop] = map[element.type];
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- if (map[element.type] != undefined) {
|
|
|
- formData.value[element.prop] = map[element.type];
|
|
|
+ } else {
|
|
|
+ for (let i = 0; i < formConfig.value.length; i++) {
|
|
|
+ const element = formConfig.value[i];
|
|
|
+ if (element.type === "picker") {
|
|
|
+ formData.value[element.prop + "Name"] = selectDataEcho(
|
|
|
+ element,
|
|
|
+ formData.value[element.prop]
|
|
|
+ );
|
|
|
+ } else if (element.type === "cascader" && element.itemType === "common") {
|
|
|
+ formData.value[element.prop + "Name"] = selectDataEcho(
|
|
|
+ element,
|
|
|
+ formData.value[element.prop]
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
emit("update:modelValue", formData.value);
|
|
|
- console.log(formData.value, "aws");
|
|
|
};
|
|
|
|
|
|
-formDataInit();
|
|
|
+formDataInit(false);
|
|
|
// 选择框 确定事件
|
|
|
const onConfirmPicker = (option, item, index) => {
|
|
|
switch (item.itemType) {
|
|
|
case "onePicker": {
|
|
|
- formData.value[item.prop + "Name"] = option.selectedOptions[0].text;
|
|
|
- formData.value[item.prop] = option.selectedOptions[0].value;
|
|
|
+ formData.value[item.prop + "Name"] =
|
|
|
+ option.selectedOptions[0][
|
|
|
+ item.fieldNames.text ? item.fieldNames.text : onePickerFieldNames.text
|
|
|
+ ];
|
|
|
+ formData.value[item.prop] =
|
|
|
+ option.selectedOptions[0][
|
|
|
+ item.fieldNames.value
|
|
|
+ ? item.fieldNames.value
|
|
|
+ : onePickerFieldNames.value
|
|
|
+ ];
|
|
|
formConfig.value[index].showPicker = false;
|
|
|
}
|
|
|
case "datePicker": {
|
|
@@ -435,18 +531,35 @@ const onConfirmPicker = (option, item, index) => {
|
|
|
const currentIndex = ref(-1);
|
|
|
const currentSonIndex = ref(-1);
|
|
|
const handleListItemClick = (i, index, sonIndex) => {
|
|
|
- currentIndex.value = index;
|
|
|
- currentSonIndex.value = sonIndex;
|
|
|
- btnConfigCopy.listConfig[sonIndex].showPicker = true;
|
|
|
+ if (i.readonly && i.readonly === true) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (i.readonly !== undefined && i.readonly === false) {
|
|
|
+ currentIndex.value = index;
|
|
|
+ currentSonIndex.value = sonIndex;
|
|
|
+ btnConfigCopy.listConfig[sonIndex].showPicker = true;
|
|
|
+ }
|
|
|
+ if (!formOption.value.readonly) {
|
|
|
+ currentIndex.value = index;
|
|
|
+ currentSonIndex.value = sonIndex;
|
|
|
+ btnConfigCopy.listConfig[sonIndex].showPicker = true;
|
|
|
+ }
|
|
|
};
|
|
|
const onConfirmListPicker = (option, item) => {
|
|
|
switch (item.itemType) {
|
|
|
case "onePicker": {
|
|
|
formData.value[btnConfigCopy.prop][currentIndex.value][
|
|
|
item.prop + "Name"
|
|
|
- ] = option.selectedOptions[0].text;
|
|
|
+ ] =
|
|
|
+ option.selectedOptions[0][
|
|
|
+ item.fieldNames.text ? item.fieldNames.text : onePickerFieldNames.text
|
|
|
+ ];
|
|
|
formData.value[btnConfigCopy.prop][currentIndex.value][item.prop] =
|
|
|
- option.selectedOptions[0].value;
|
|
|
+ option.selectedOptions[0][
|
|
|
+ item.fieldNames.value
|
|
|
+ ? item.fieldNames.value
|
|
|
+ : onePickerFieldNames.value
|
|
|
+ ];
|
|
|
btnConfigCopy.listConfig[currentSonIndex.value].showPicker = false;
|
|
|
}
|
|
|
case "datePicker": {
|
|
@@ -538,14 +651,86 @@ const getAreaInfo = (selectedOptions, item, index) => {
|
|
|
});
|
|
|
};
|
|
|
// 城市变动事件
|
|
|
-const cityOnChange = (selectedOptions, item, index) => {
|
|
|
- getAreaInfo(selectedOptions, item, index);
|
|
|
+const cityOnChange = (options, item, index) => {
|
|
|
+ getAreaInfo(options, item, index);
|
|
|
};
|
|
|
|
|
|
const commonOnChange = ({ selectedOptions }, item, index) => {
|
|
|
formData.value[item.prop + "Name"] =
|
|
|
selectedOptions[selectedOptions.length - 1].label;
|
|
|
};
|
|
|
+// 文件上传
|
|
|
+const onOversize = () => {
|
|
|
+ showToast("文件大小不能超过 5MB");
|
|
|
+};
|
|
|
+
|
|
|
+const afterRead = (file) => {
|
|
|
+ if (file && file.length > 0) {
|
|
|
+ for (let i = 0; i < file.length; i++) {
|
|
|
+ file[i].status = "uploading";
|
|
|
+ file[i].message = "上传中...";
|
|
|
+ proxy.post("/fileInfo/getSing", { fileName: file[i].file.name }).then(
|
|
|
+ (res) => {
|
|
|
+ let forms = new FormData();
|
|
|
+ forms.append("file", file[i].file);
|
|
|
+ proxy
|
|
|
+ .post("https://winfaster.obs.cn-south-1.myhuaweicloud.com", {
|
|
|
+ ...res.data.uploadBody,
|
|
|
+ file: forms.get("file"),
|
|
|
+ })
|
|
|
+ .then(
|
|
|
+ () => {
|
|
|
+ file[i].id = res.data.id;
|
|
|
+ file[i].url = res.data.fileUrl;
|
|
|
+ file[i].fileName = res.data.fileName;
|
|
|
+ delete file[i].status;
|
|
|
+ delete file[i].message;
|
|
|
+ },
|
|
|
+ () => {
|
|
|
+ file[i].status = "failed";
|
|
|
+ file[i].message = "上传失败";
|
|
|
+ }
|
|
|
+ );
|
|
|
+ },
|
|
|
+ () => {
|
|
|
+ file[i].status = "failed";
|
|
|
+ file[i].message = "上传失败";
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ file.status = "uploading";
|
|
|
+ file.message = "上传中...";
|
|
|
+ proxy.post("/fileInfo/getSing", { fileName: file.file.name }).then(
|
|
|
+ (res) => {
|
|
|
+ let forms = new FormData();
|
|
|
+ forms.append("file", file.file);
|
|
|
+ proxy
|
|
|
+ .post("https://winfaster.obs.cn-south-1.myhuaweicloud.com", {
|
|
|
+ ...res.data.uploadBody,
|
|
|
+ file: forms.get("file"),
|
|
|
+ })
|
|
|
+ .then(
|
|
|
+ () => {
|
|
|
+ file.id = res.data.id;
|
|
|
+ file.url = res.data.fileUrl;
|
|
|
+ file.fileName = res.data.fileName;
|
|
|
+ delete file.status;
|
|
|
+ delete file.message;
|
|
|
+ },
|
|
|
+ () => {
|
|
|
+ file.status = "failed";
|
|
|
+ file.message = "上传失败";
|
|
|
+ }
|
|
|
+ );
|
|
|
+ },
|
|
|
+ () => {
|
|
|
+ file.status = "failed";
|
|
|
+ file.message = "上传失败";
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+};
|
|
|
const testForm = ref(null); // 延迟使用,因为还没有返回跟挂载
|
|
|
watch(
|
|
|
formData.value,
|
|
@@ -556,6 +741,11 @@ watch(
|
|
|
deep: true,
|
|
|
}
|
|
|
);
|
|
|
+
|
|
|
+defineExpose({
|
|
|
+ formDataInit,
|
|
|
+});
|
|
|
+// onMounted(() => {});
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|