Parcourir la source

表单验证增加返回值

cz il y a 2 ans
Parent
commit
0dd26a7551

+ 345 - 337
src/components/byForm/index.vue

@@ -1,371 +1,379 @@
 <template>
-	<div class="by-form">
-		<el-form
-			:model="formData"
-			:label-width="formOption.labelWidth"
-			:inline="formOption.inline || false"
-			:rules="rules"
-			:labelPosition="formOption.labelPosition || 'top'"
-			ref="byForm"
-		>
-			<el-form-item
-				:label="i.label"
-				v-for="i in formConfig"
-				:key="i.model"
-				:prop="i.prop"
-				v-show="i.isShow || i.isShow == undefined"
-				:style="
-					i.type == 'title' ? 'width:100%' :
-						i.itemWidth
-						? 'width:' + i.itemWidth + '%'
-						: formOption.itemWidth
-						? 'width:' + formOption.itemWidth + '%'
-						: '100%'
-				"
-				:class="i.isHide ? 'dn' : ''"
-			>
-				<el-input
-					v-if="i.type == 'input'"
-					v-model="formData[i.prop]"
-					:placeholder="i.placeholder || '请输入'"
-					@input="((e)=>commonsEmit(e,i))"
-					:type="i.itemType ? i.itemType : 'text'"
-					:disabled="i.disabled ? i.disabled : false"
-					:max="i.max"
-					:min="i.min"
-					:maxlength="i.maxlength"
-				/>
-				<el-select
-					v-model="formData[i.prop]"
-					:multiple="i.multiple || false"
-					v-else-if="i.type == 'select'"
-					:placeholder="i.placeholder || '请选择'"
-					@change="((e)=>commonsEmit(e,i))"
-					:disabled="i.disabled ? i.disabled : false"
-					:style="i.style"
-				>
-					<el-option :label="j.title || j.name || j.label" :value="j.id || j.value" v-for="j in i.data" :key="j.id">
-					</el-option>
-				</el-select>
-				<el-tree-select
-					v-model="formData[i.prop]"
-					v-else-if="i.type == 'treeSelect'"
-					:data="i.data"
-					:props="{ value: i.propsTreeValue || 'id', label: i.propsTreeLabel || 'label', children: i.propsTreeChildren || 'children' }"
-					value-key="id"
-					:placeholder="i.placeholder || '请选择'"
-					check-strictly
-				/>
-				<el-date-picker
-					v-model="formData[i.prop]"
-					v-else-if="i.type == 'date'"
-					:type="i.itemType"
-					:placeholder="i.placeholder || '请选择时间'"
-					@change="commonsEmit"
-					:disabled="i.disabled ? i.disabled : false"
-					:format="i.format ? i.format : dateFormatInit(i.itemType)"
-      				:value-format="i.format ? i.format : dateFormatInit(i.itemType)"
-				/>
-				<el-switch
-					:disabled="i.disabled ? i.disabled : false"
-					v-else-if="i.type == 'switch'"
-					v-model="formData[i.prop]"
-				/>
-				<el-checkbox-group
-					v-else-if="i.type == 'checkbox'"
-					v-model="formData[i.prop]"
-					:disabled="i.disabled ? i.disabled : false"
-				>
-					<el-checkbox  v-for="j in i.data" :key="j.id || j.value" ::label="j.id  || j.value" name="type">
-						{{ j.name || j.label }}
-					</el-checkbox>
-					
-				</el-checkbox-group>
-				<el-radio-group
-					v-else-if="i.type == 'radio'"
-					v-model="formData[i.prop]"
-					:disabled="i.disabled ? i.disabled : false"
-					
-				>
-					<el-radio 
-						:border="i.border ? i.border : false"
-						v-for="j in i.data" :key="j.id || j.value" :label="j.id  || j.value" name="type"
-					>
-						{{ j.name || j.label }}
-					</el-radio>
-				</el-radio-group>
-				<el-input-number
-					v-else-if="i.type == 'number'"
-					v-model="formData[i.prop]"
-					:placeholder="i.placeholder || '请输入'"
-					@input="commonsEmit"
-					:disabled="i.disabled ? i.disabled : false"
-					:min="i.min ? i.min : 0"
-					:max="i.max ? i.max : 100"
-					:step="i.step ? i.step : 1">
-				</el-input-number>
-				<el-tree
-					v-else-if="i.type == 'tree'"
-					:data="i.data"
-					:props="i.props"
-					:show-checkbox="i.showCheckbox || true"
-				>
-				</el-tree>
-				<el-cascader
-					v-else-if="i.type == 'cascader'"
-					:options="i.data"
-					:props="i.props"
-					:placeholder="i.placeholder || '请选择'"
-					@change="commonsEmit"
-					:disabled="i.disabled ? i.disabled : false"
-					:style="i.style">
-				</el-cascader>
-				<div class="form-title" v-else-if="i.type == 'title'">
-					{{ i.title }}
-				</div>
-				<slot 
-                    :name="i.slotName" 
-                    v-else-if="i.type == 'slot'">
-                    {{i.slotName}}插槽占位符
-                </slot>
-				<div v-else-if="i.type == 'json'">
-					<byForm
-						:formConfig="i.json"
-						:formOption="formOption"
-						v-model="formData[i.prop]"
-						ref="byform"
-					>
-					</byForm>
-				</div>
-			</el-form-item>
-		</el-form>
-	</div>
+  <div class="by-form">
+    <el-form
+      :model="formData"
+      :label-width="formOption.labelWidth"
+      :inline="formOption.inline || false"
+      :rules="rules"
+      :labelPosition="formOption.labelPosition || 'top'"
+      ref="byForm"
+    >
+      <el-form-item
+        :label="i.label"
+        v-for="i in formConfig"
+        :key="i.model"
+        :prop="i.prop"
+        v-show="i.isShow || i.isShow == undefined"
+        :style="
+          i.type == 'title'
+            ? 'width:100%'
+            : i.itemWidth
+            ? 'width:' + i.itemWidth + '%'
+            : formOption.itemWidth
+            ? 'width:' + formOption.itemWidth + '%'
+            : '100%'
+        "
+        :class="i.isHide ? 'dn' : ''"
+      >
+        <el-input
+          v-if="i.type == 'input'"
+          v-model="formData[i.prop]"
+          :placeholder="i.placeholder || '请输入'"
+          @input="(e) => commonsEmit(e, i)"
+          :type="i.itemType ? i.itemType : 'text'"
+          :disabled="i.disabled ? i.disabled : false"
+          :max="i.max"
+          :min="i.min"
+          :maxlength="i.maxlength"
+        />
+        <el-select
+          v-model="formData[i.prop]"
+          :multiple="i.multiple || false"
+          v-else-if="i.type == 'select'"
+          :placeholder="i.placeholder || '请选择'"
+          @change="(e) => commonsEmit(e, i)"
+          :disabled="i.disabled ? i.disabled : false"
+          :style="i.style"
+        >
+          <el-option
+            :label="j.title || j.name || j.label"
+            :value="j.id || j.value"
+            v-for="j in i.data"
+            :key="j.id"
+          >
+          </el-option>
+        </el-select>
+        <el-tree-select
+          v-model="formData[i.prop]"
+          v-else-if="i.type == 'treeSelect'"
+          :data="i.data"
+          :props="{
+            value: i.propsTreeValue || 'id',
+            label: i.propsTreeLabel || 'label',
+            children: i.propsTreeChildren || 'children',
+          }"
+          value-key="id"
+          :placeholder="i.placeholder || '请选择'"
+          check-strictly
+        />
+        <el-date-picker
+          v-model="formData[i.prop]"
+          v-else-if="i.type == 'date'"
+          :type="i.itemType"
+          :placeholder="i.placeholder || '请选择时间'"
+          @change="commonsEmit"
+          :disabled="i.disabled ? i.disabled : false"
+          :format="i.format ? i.format : dateFormatInit(i.itemType)"
+          :value-format="i.format ? i.format : dateFormatInit(i.itemType)"
+        />
+        <el-switch
+          :disabled="i.disabled ? i.disabled : false"
+          v-else-if="i.type == 'switch'"
+          v-model="formData[i.prop]"
+        />
+        <el-checkbox-group
+          v-else-if="i.type == 'checkbox'"
+          v-model="formData[i.prop]"
+          :disabled="i.disabled ? i.disabled : false"
+        >
+          <el-checkbox
+            v-for="j in i.data"
+            :key="j.id || j.value"
+            ::label="j.id  || j.value"
+            name="type"
+          >
+            {{ j.name || j.label }}
+          </el-checkbox>
+        </el-checkbox-group>
+        <el-radio-group
+          v-else-if="i.type == 'radio'"
+          v-model="formData[i.prop]"
+          :disabled="i.disabled ? i.disabled : false"
+        >
+          <el-radio
+            :border="i.border ? i.border : false"
+            v-for="j in i.data"
+            :key="j.id || j.value"
+            :label="j.id || j.value"
+            name="type"
+          >
+            {{ j.name || j.label }}
+          </el-radio>
+        </el-radio-group>
+        <el-input-number
+          v-else-if="i.type == 'number'"
+          v-model="formData[i.prop]"
+          :placeholder="i.placeholder || '请输入'"
+          @input="commonsEmit"
+          :disabled="i.disabled ? i.disabled : false"
+          :min="i.min ? i.min : 0"
+          :max="i.max ? i.max : 100"
+          :step="i.step ? i.step : 1"
+        >
+        </el-input-number>
+        <el-tree
+          v-else-if="i.type == 'tree'"
+          :data="i.data"
+          :props="i.props"
+          :show-checkbox="i.showCheckbox || true"
+        >
+        </el-tree>
+        <el-cascader
+          v-else-if="i.type == 'cascader'"
+          :options="i.data"
+          :props="i.props"
+          :placeholder="i.placeholder || '请选择'"
+          @change="commonsEmit"
+          :disabled="i.disabled ? i.disabled : false"
+          :style="i.style"
+        >
+        </el-cascader>
+        <div class="form-title" v-else-if="i.type == 'title'">
+          {{ i.title }}
+        </div>
+        <slot :name="i.slotName" v-else-if="i.type == 'slot'">
+          {{ i.slotName }}插槽占位符
+        </slot>
+        <div v-else-if="i.type == 'json'">
+          <byForm
+            :formConfig="i.json"
+            :formOption="formOption"
+            v-model="formData[i.prop]"
+            ref="byform"
+          >
+          </byForm>
+        </div>
+      </el-form-item>
+    </el-form>
+  </div>
 </template>
 <script>
-	export default {
-	  name: "byForm", 
-	}
+export default {
+  name: "byForm",
+};
 </script>
 <script  setup>
-import { set } from '@vueuse/shared'
-import { reactive } from 'vue'
+import { set } from "@vueuse/shared";
+import { reactive } from "vue";
 defineProps({
-	modelValue: {
-		type: Object,
-		default: false,
-	},
-	formConfig: {
-		type: Array,
-		default: false,
-	},
-	disabled: {
-		type: Boolean,
-		default: false,
-	},
-	formOption: {
-		type: Object,
-		default: false,
-	},
-	rules: {
-		type: Object,
-		default: false,
-	},
-})
+  modelValue: {
+    type: Object,
+    default: false,
+  },
+  formConfig: {
+    type: Array,
+    default: false,
+  },
+  disabled: {
+    type: Boolean,
+    default: false,
+  },
+  formOption: {
+    type: Object,
+    default: false,
+  },
+  rules: {
+    type: Object,
+    default: false,
+  },
+});
 
-const isInit = ref(false)
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['update:modelValue'])
+const isInit = ref(false);
+const { proxy } = getCurrentInstance();
+const emit = defineEmits(["update:modelValue"]);
 const formData = computed(() => {
-	return proxy.modelValue	
-})
-const formDataReset = ref({...proxy.modelValue})
-const commonsEmit = (prop,item) => {
-	console.log(formData)
-	if(item.fn) {
-		item.fn(prop)
-	}
-	emit('update:modelValue', formData.value)
-}
+  return proxy.modelValue;
+});
+const formDataReset = ref({ ...proxy.modelValue });
+const commonsEmit = (prop, item) => {
+  console.log(formData);
+  if (item.fn) {
+    item.fn(prop);
+  }
+  emit("update:modelValue", formData.value);
+};
 const loadInit = () => {
-	const v = this
-	for (let i = 0; i < proxy.formConfig.length; i++) {
-		const element = proxy.formConfig[i]
-		if (element.isLoad) {
-			commonGetdata(element.isLoad, i)
-		}
-	}
-}
-const dateFormatInit = ((itemType) => {
-	const formatObj = {
-		year:"YYYY",
-		month:"YYYY-MM",
-		date:"YYYY-MM-DD hh:mm:ss",
-		dates:'YYYY-MM-DD',
-		datetime:"YYYY-MM-DD hh:mm:ss",
-		monthrange:"YYYY-MM-DD hh:mm:ss",
-		datetimerange:"YYYY-MM-DD hh:mm:ss",
-		daterange:"YYYY-MM-DD hh:mm:ss",
-	}
-	console.log(formatObj)
-	return formatObj[itemType]
-})
+  const v = this;
+  for (let i = 0; i < proxy.formConfig.length; i++) {
+    const element = proxy.formConfig[i];
+    if (element.isLoad) {
+      commonGetdata(element.isLoad, i);
+    }
+  }
+};
+const dateFormatInit = (itemType) => {
+  const formatObj = {
+    year: "YYYY",
+    month: "YYYY-MM",
+    date: "YYYY-MM-DD hh:mm:ss",
+    dates: "YYYY-MM-DD",
+    datetime: "YYYY-MM-DD hh:mm:ss",
+    monthrange: "YYYY-MM-DD hh:mm:ss",
+    datetimerange: "YYYY-MM-DD hh:mm:ss",
+    daterange: "YYYY-MM-DD hh:mm:ss",
+  };
+  console.log(formatObj);
+  return formatObj[itemType];
+};
 
 //公用递归,保证key,val统一
 const commonRecursive = (arr, labelKey, labelVal, childrenName) => {
-	for (let i = 0; i < arr.length; i++) {
-		console.log(arr[i])
-		if(labelKey == 'stringArray'){
-			arr[i] = {
-				label:arr[i],
-				value:arr[i],
-				id:arr[i],
-				title:arr[i],
-			}
-		}else{
-			arr[i].title = arr[i].label = arr[i][labelKey]
-			arr[i].id = arr[i].value = arr[i][labelVal]
-		}
-		
-		if (childrenName) {
-			arr[i].children = arr[i][childrenName]
-		}
-		arr[i].checked = false
-		typeof arr[i][labelVal] == String
-			? (arr[i].key = arr[i][labelVal])
-			: (arr[i].key = JSON.stringify(arr[i][labelVal]))
-		if (childrenName) {
-			this.commonRecursive(
-				arr[i][childrenName],
-				labelKey,
-				labelVal,
-				childrenName
-			)
-		}
-	}
-}
+  for (let i = 0; i < arr.length; i++) {
+    console.log(arr[i]);
+    if (labelKey == "stringArray") {
+      arr[i] = {
+        label: arr[i],
+        value: arr[i],
+        id: arr[i],
+        title: arr[i],
+      };
+    } else {
+      arr[i].title = arr[i].label = arr[i][labelKey];
+      arr[i].id = arr[i].value = arr[i][labelVal];
+    }
 
-//请求form表单所需数据字典
-const commonGetdata = (isLoad,i) => {
-	proxy[isLoad.method](isLoad.url,isLoad.req).then(message=>{
-		console.log(message)
-		if (getFormat(isLoad.resUrl, message) == undefined) {
-			console.log('请查看isLoad配置是否正确url:' + isLoad.url)
-			return
-		}
-		proxy.formConfig[i].data = getFormat(isLoad.resUrl, message)
-		if (isLoad.labelKey) {
-			commonRecursive(
-				proxy.formConfig[i].data,
-				isLoad.labelKey,
-				isLoad.labelVal,
-				isLoad.childrenName
-			)
-		}
-		console.log(proxy.formConfig[i].data)
-	})
-}
+    if (childrenName) {
+      arr[i].children = arr[i][childrenName];
+    }
+    arr[i].checked = false;
+    typeof arr[i][labelVal] == String
+      ? (arr[i].key = arr[i][labelVal])
+      : (arr[i].key = JSON.stringify(arr[i][labelVal]));
+    if (childrenName) {
+      this.commonRecursive(
+        arr[i][childrenName],
+        labelKey,
+        labelVal,
+        childrenName
+      );
+    }
+  }
+};
 
+//请求form表单所需数据字典
+const commonGetdata = (isLoad, i) => {
+  proxy[isLoad.method](isLoad.url, isLoad.req).then((message) => {
+    console.log(message);
+    if (getFormat(isLoad.resUrl, message) == undefined) {
+      console.log("请查看isLoad配置是否正确url:" + isLoad.url);
+      return;
+    }
+    proxy.formConfig[i].data = getFormat(isLoad.resUrl, message);
+    if (isLoad.labelKey) {
+      commonRecursive(
+        proxy.formConfig[i].data,
+        isLoad.labelKey,
+        isLoad.labelVal,
+        isLoad.childrenName
+      );
+    }
+    console.log(proxy.formConfig[i].data);
+  });
+};
 
 //根据resurl获取数据
 const getFormat = (formatStr, props) => {
-	if(!formatStr)  return props
-	return formatStr
-		.split('.')
-		.reduce((total, cur) => (!total ? '' : total[cur]), props)
-}
+  if (!formatStr) return props;
+  return formatStr
+    .split(".")
+    .reduce((total, cur) => (!total ? "" : total[cur]), props);
+};
 
 //初始化所有表单
 
 const formDataInit = () => {
-	
-	
-	var map = {
-		input: '',
-		radio: null,
-		select: null,
-		checkbox: [],
-		date: '',
-		datetime: '',
-		daterange: [],
-		datetimerange: [],
-		year: null,
-		month: null,
-		switch: false,
-		inputNumber: 0,
-		cascader: [],
-		Solt: null,
-		Transfer: [],
-		Upload: { path: null, id: null, name: null },
-		password:'',
-		treeSelect:'',
-		json:{},
-	}
-	const formDataCopy = { ...formData.value }
-	for (let i = 0; i < proxy.formConfig.length; i++) {
-		const element = proxy.formConfig[i]
-		
-		if(formDataCopy[element.prop] || element.type === 'slot') {
-			continue
-		}
-			
-		if(map[element.itemType] != undefined){
-			formData.value[element.prop] = map[element.itemType]
-		}else{
-			formData.value[element.prop] = element.multiple ? [] :  map[element.type]
-		}
-		
-	}
-	
-	emit('update:modelValue', formData.value)
-}
+  var map = {
+    input: "",
+    radio: null,
+    select: null,
+    checkbox: [],
+    date: "",
+    datetime: "",
+    daterange: [],
+    datetimerange: [],
+    year: null,
+    month: null,
+    switch: false,
+    inputNumber: 0,
+    cascader: [],
+    Solt: null,
+    Transfer: [],
+    Upload: { path: null, id: null, name: null },
+    password: "",
+    treeSelect: "",
+    json: {},
+  };
+  const formDataCopy = { ...formData.value };
+  for (let i = 0; i < proxy.formConfig.length; i++) {
+    const element = proxy.formConfig[i];
+
+    if (formDataCopy[element.prop] || element.type === "slot") {
+      continue;
+    }
+
+    if (map[element.itemType] != undefined) {
+      formData.value[element.prop] = map[element.itemType];
+    } else {
+      formData.value[element.prop] = element.multiple ? [] : map[element.type];
+    }
+  }
+
+  emit("update:modelValue", formData.value);
+};
 
 const handleSubmit = (onSubmit) => {
-	proxy.$refs['byForm'].validate((valid) => {
-		if (valid) {
-			const form = { ...formData.value }
-			proxy.formConfig.map(item => {
-				if(item.type == 'json') {
-					form[item.prop] = JSON.stringify(form[item.prop])
-				}
-			})
-			emit('update:modelValue', form)
-			onSubmit()
-		// } else {
-		// 	ElMessage({
-		// 		message: '请检查表单',
-		// 		type: 'warning',
-		// 	})
-		}
-	})
-}
-const byform = ref(null) // 延迟使用,因为还没有返回跟挂载
-onMounted(()=>{
-	
-})
+  proxy.$refs["byForm"].validate((valid) => {
+    if (valid) {
+      const form = { ...formData.value };
+      proxy.formConfig.map((item) => {
+        if (item.type == "json") {
+          form[item.prop] = JSON.stringify(form[item.prop]);
+        }
+      });
+      emit("update:modelValue", form);
+      onSubmit();
+      // } else {
+      // 	ElMessage({
+      // 		message: '请检查表单',
+      // 		type: 'warning',
+      // 	})
+    }
+    return valid; //无论是否验证通过都返回
+  });
+};
+const byform = ref(null); // 延迟使用,因为还没有返回跟挂载
+onMounted(() => {});
 defineExpose({
-	handleSubmit,
-})
-formDataInit()
-loadInit()
+  handleSubmit,
+});
+formDataInit();
+loadInit();
 </script>
 
 <style>
-
 .form-title {
-	font-size: 14px;
-	font-weight: bold;
-	margin-top: 22px;
-	color: #333333;
+  font-size: 14px;
+  font-weight: bold;
+  margin-top: 22px;
+  color: #333333;
 }
 .by-form .el-form--inline .el-form-item {
-	margin-right: 0px;
-	padding-right: 32px;
-	box-sizing: border-box;
+  margin-right: 0px;
+  padding-right: 32px;
+  box-sizing: border-box;
 }
 
-.dn{
-	display: none!important;
+.dn {
+  display: none !important;
 }
-
-
 </style>

+ 192 - 0
src/components/process/ReturnGood.vue

@@ -0,0 +1,192 @@
+<template>
+  <div style="width: 100%; padding: 0px 15px">
+    <byForm
+      :formConfig="formConfig"
+      :formOption="formOption"
+      v-model="formData.data"
+      :rules="rules"
+      ref="formDom"
+    >
+      <template #details>
+        <div>
+          <el-button type="primary" @click="openProduct = true">
+            添加物品
+          </el-button>
+          <el-table :data="formData.data.purchaseDetailList">
+            <el-table-column prop="productCode" label="货品编码" />
+            <el-table-column prop="productName" label="货品名称" />
+            <el-table-column prop="productSpec" label="规格型号" />
+            <el-table-column prop="productUnit" label="单位" />
+
+            <el-table-column prop="price" label="退货数量" min-width="150">
+              <template #default="{ row, $index }">
+                <el-form-item
+                  :prop="'purchaseDetailList.' + $index + '.price'"
+                  :rules="rules.price"
+                  :inline-message="true"
+                >
+                  <el-input-number
+                    v-model="row.price"
+                    :precision="4"
+                    :controls="false"
+                    :min="0"
+                  />
+                </el-form-item>
+              </template>
+            </el-table-column>
+            <el-table-column prop="price" label="退货原因" min-width="150">
+              <template #default="{ row, $index }">
+                <el-form-item
+                  :prop="'purchaseDetailList.' + $index + '.price'"
+                  :rules="rules.price"
+                  :inline-message="true"
+                >
+                  <el-input v-model="row.price" placeholder="请输入" />
+                </el-form-item>
+              </template>
+            </el-table-column>
+            <el-table-column prop="zip" label="操作" width="100">
+              <template #default="{ $index }">
+                <el-button type="primary" link @click="handleRemove($index)"
+                  >删除</el-button
+                >
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </template>
+    </byForm>
+    <el-dialog
+      v-model="openProduct"
+      title="选择货品"
+      width="70%"
+      append-to-body
+    >
+      <SelectGoods
+        @cancel="openProduct = false"
+        @pushGoods="pushGoods"
+      ></SelectGoods>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import byForm from "@/components/byForm/index";
+import SelectGoods from "@/components/product/SelectGoods";
+
+let formData = reactive({
+  data: {
+    name: "",
+    processRouteList: [],
+    remarks: "",
+    productList: [],
+  },
+});
+let rules = ref({
+  name: [{ required: true, message: "请输入工艺名称", trigger: "blur" }],
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "input",
+      prop: "name",
+      label: "申请部门",
+      itemWidth: 25,
+      style: {
+        "margin-right": "10px",
+      },
+    },
+    {
+      type: "input",
+      prop: "name",
+      label: "申请人",
+      itemWidth: 25,
+      style: {
+        "margin-right": "10px",
+      },
+    },
+    {
+      type: "date",
+      prop: "name",
+      label: "申请时间",
+      itemWidth: 25,
+      style: {
+        "margin-right": "10px",
+      },
+    },
+    {
+      type: "select",
+      prop: "productId",
+      label: "供应商",
+      isLoad: {
+        url: "/supplierInfo/page",
+        req: {
+          pageNum: 1,
+          pageSize: 9999,
+        },
+        labelKey: "name",
+        labelVal: "id",
+        method: "post",
+        resUrl: "rows",
+      },
+    },
+    {
+      type: "slot",
+      slotName: "details",
+      label: "退货明细",
+    },
+  ];
+});
+const formDom = ref(null);
+const handleSubmit = async () => {
+  formDom.value.handleSubmit((vaild) => {
+    console.log(vaild, "wsdaws");
+  });
+};
+let openProduct = ref(false);
+const handleRemove = (index) => {
+  formData.data.purchaseDetailList.splice(index, 1);
+  return ElMessage({
+    message: "删除成功!",
+    type: "success",
+  });
+};
+const pushGoods = (goods) => {
+  const arr = goods.map((x) => ({
+    goodType: x.goodType,
+    productCode: x.code,
+    productName: x.name,
+    productSpec: x.spec,
+    productUnit: x.unit,
+    count: 0,
+    price: 0,
+    bussinessId: x.id,
+    amount: 0,
+  }));
+  formData.data.purchaseDetailList =
+    formData.data.purchaseDetailList.concat(arr);
+  return ElMessage({
+    message: "添加成功!",
+    type: "success",
+  });
+};
+
+// 接收父组件的传值
+const props = defineProps({
+  queryData: String,
+});
+
+// 向父组件暴露
+defineExpose({
+  submitData: formData.data,
+  handleSubmit,
+});
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 7 - 0
src/views/process/processApproval/index.vue

@@ -17,6 +17,11 @@
           v-else-if="queryData.data.isSubscribe == '30'"
           :queryData="queryData.data"
         ></SendFunds>
+        <ReturnGood
+          ref="makeDom"
+          v-else-if="queryData.data.isSubscribe == '40'"
+          :queryData="queryData.data"
+        ></ReturnGood>
       </div>
       <div class="bottom">
         <div class="commons-title title">处理意见</div>
@@ -185,6 +190,8 @@ import SendSubscribe from "@/components/process/SendSubscribe";
 import SendPurchase from "@/components/process/SendPurchase";
 //请款发起
 import SendFunds from "@/components/process/SendFunds";
+//退货
+import ReturnGood from "@/components/process/ReturnGood";
 // 消息提示
 import { ElMessage, ElMessageBox } from "element-plus";
 // tab切换逻辑

+ 29 - 19
src/views/purchaseManage/purchaseManage/arrival/index.vue

@@ -17,7 +17,7 @@
           {
             text: '质检',
             disabled: selectData.length === 0,
-            action: () => start(),
+            action: () => start(20),
           },
         ]"
         @get-list="getList"
@@ -176,6 +176,12 @@ let modalType = ref("add");
 let fileList = ref([]);
 let rules = ref({
   name: [{ required: true, message: "请输入供应商名称", trigger: "blur" }],
+  qualifiedCount: [
+    { required: true, message: "请输入质检合格数量", trigger: "blur" },
+  ],
+  noQualifiedCount: [
+    { required: true, message: "请输入质检不合格数量", trigger: "blur" },
+  ],
 });
 const { proxy } = getCurrentInstance();
 const selectConfig = reactive([
@@ -348,22 +354,37 @@ const getList = async (req) => {
 
 const submitForm = () => {
   formDom.value.validate((valid) => {
-    submitLoading.value = true;
     const list = formData.data.qualityDetailList;
-
-    proxy.post("/productionProcesses/" + modalType.value, formData.data).then(
+    for (let i = 0; i < list.length; i++) {
+      const e = list[i];
+      if (!(e.qualifiedCount + e.noQualifiedCount > 0)) {
+        return ElMessage({
+          message: "质检数量不能为0!",
+          type: "info",
+        });
+      }
+      if (
+        e.qualifiedCount + e.noQualifiedCount + Number(e.sumQualityCount) >
+        Number(e.count)
+      ) {
+        return ElMessage({
+          message: "质检数量不能大于到货数量!",
+          type: "info",
+        });
+      }
+    }
+    submitLoading.value = true;
+    proxy.post("/quality/" + modalType.value, formData.data).then(
       (res) => {
         ElMessage({
-          message: modalType.value == "add" ? "添加成功" : "编辑成功",
+          message: "质检成功",
           type: "success",
         });
-        fileList.value = [];
         dialogVisible.value = false;
         submitLoading.value = false;
         getList();
       },
       (err) => {
-        console.log(err, "aswwwww");
         submitLoading.value = false;
       }
     );
@@ -396,6 +417,7 @@ const selectRow = (data) => {
 };
 
 const start = (type) => {
+  modalType.value = "add";
   let ids = [];
   let row = {};
   if (type === 10) {
@@ -414,7 +436,6 @@ const start = (type) => {
       qualityDetailList: res.map((x) => ({
         ...x,
         arrivalDetailId: x.id,
-        purchaseCount: x.count,
         qualifiedCount: 0,
         noQualifiedCount: 0,
       })),
@@ -423,17 +444,6 @@ const start = (type) => {
   });
 };
 
-// 获取供应商数据
-const supplierData = ref([]);
-const getSupplierList = async (req) => {
-  proxy
-    .post("/supplierInfo/page", { pageNum: 1, pageSize: 9999 })
-    .then((res) => {
-      supplierData.value = res.rows;
-    });
-};
-getSupplierList();
-
 watch(selectData, (newVal, oldVal) => {
   if (newVal.length == 0) {
     sourceList.value.data.forEach((x) => {

+ 479 - 0
src/views/purchaseManage/purchaseManage/returnGoods/index.vue

@@ -0,0 +1,479 @@
+<template>
+  <div class="tenant">
+    <!-- <Banner /> -->
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :table-events="{
+          //element talbe事件都能传
+        }"
+        :action-list="[
+          {
+            text: '添加退货',
+            action: () => start(),
+          },
+        ]"
+        @get-list="getList"
+      >
+        <template #fileSlot="{ item }">
+          <div
+            style="cursor: pointer; color: #409eff"
+            @click="handleClickFile(item)"
+          >
+            {{ item.fileName }}
+          </div>
+        </template>
+      </byTable>
+    </div>
+    <el-dialog
+      title="到货通知"
+      v-model="dialogVisible"
+      width="800"
+      v-loading="loading"
+    >
+      <el-form
+        :model="formData.data"
+        :rules="rules"
+        ref="formDom"
+        label-position="top"
+      >
+        <div style="margin-bottom: 10px; font-size: 14px">基础信息</div>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="供应商" prop="supplyId">
+              <el-select
+                v-model="formData.data.supplyId"
+                placeholder="请选择"
+                style="width: 100%"
+                disabled
+              >
+                <el-option
+                  v-for="item in supplierData"
+                  :label="item.name"
+                  :value="item.id"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="6">
+            <el-form-item label="采购单号" prop="code">
+              <el-input
+                v-model="formData.data.code"
+                placeholder="请输入"
+                disabled
+              >
+              </el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <div style="margin-bottom: 10px; font-size: 14px">到货明细</div>
+        <el-form-item>
+          <el-table :data="formData.data.arrivalDetailList">
+            <el-table-column
+              prop="goodType"
+              label="货品类型"
+              :formatter="(row) => (row.goodType == 1 ? '产品' : '物料')"
+            />
+            <el-table-column prop="productCode" label="货品编码" />
+            <el-table-column prop="productName" label="货品名称" />
+            <el-table-column prop="productSpec" label="规格型号" />
+            <el-table-column prop="productUnit" label="单位" />
+            <el-table-column prop="purchaseCount" label="采购数量" />
+            <el-table-column prop="sumArrivalCount" label="已到货" />
+            <el-table-column prop="count" label="本次到货" min-width="150">
+              <template #default="{ row, $index }">
+                <el-form-item
+                  :prop="'arrivalDetailList.' + $index + '.count'"
+                  :rules="rules.count"
+                  :inline-message="true"
+                >
+                  <el-input-number
+                    v-model="row.count"
+                    :precision="4"
+                    :controls="false"
+                    :min="0"
+                    @change="handleChangeAmount"
+                  />
+                </el-form-item>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-form-item>
+      </el-form>
+
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm()"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+  
+<script setup>
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+
+const loading = ref(false);
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+  },
+});
+let dialogVisible = ref(false);
+let modalType = ref("add");
+let rules = ref({
+  count: [{ required: true, message: "请输入本次到货", trigger: "blur" }],
+});
+const { proxy } = getCurrentInstance();
+const selectConfig = reactive([
+  {
+    label: "退货状态",
+    prop: "status",
+    data: [
+      {
+        label: "审批中",
+        value: "10",
+      },
+      {
+        label: "驳回",
+        value: "20",
+      },
+      {
+        label: "待退货",
+        value: "30",
+      },
+    ],
+  },
+  {
+    label: "到货状态",
+    prop: "arrivalStatus",
+    data: [
+      {
+        label: "未到货",
+        value: "0",
+      },
+      {
+        label: "部分到货",
+        value: "10",
+      },
+      {
+        label: "已到货",
+        value: "20",
+      },
+    ],
+  },
+  {
+    label: "付款状态",
+    prop: "payStatus",
+    data: [
+      {
+        label: "未付款",
+        value: "1",
+      },
+      {
+        label: "部分付款",
+        value: "2",
+      },
+      {
+        label: "已付款",
+        value: "3",
+      },
+    ],
+  },
+]);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "退货单号",
+        prop: "code",
+      },
+    },
+    {
+      attrs: {
+        label: "供应商",
+        prop: "supplyName",
+      },
+    },
+
+    {
+      attrs: {
+        label: "物品编码",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "物品名称",
+        prop: "purchaseName",
+      },
+    },
+    {
+      attrs: {
+        label: "单位",
+        prop: "createTime",
+      },
+    },
+    {
+      attrs: {
+        label: "退货数量",
+        prop: "purchaseStatus",
+      },
+    },
+    {
+      attrs: {
+        label: "退货状态",
+        prop: "arrivalStatus",
+      },
+    },
+    {
+      attrs: {
+        label: "退款状态",
+        prop: "payStatus",
+      },
+    },
+    {
+      attrs: {
+        label: "操作人",
+        prop: "payStatus",
+      },
+    },
+    {
+      attrs: {
+        label: "操作时间",
+        prop: "payStatus",
+      },
+    },
+
+    {
+      attrs: {
+        label: "操作",
+        width: "100",
+        align: "right",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "结束",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              handleEdit(row, 99);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+
+let formData = reactive({
+  data: {
+    type: "1",
+  },
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formDom = ref(null);
+const formConfig = computed(() => {
+  return [
+    {
+      type: "radio",
+      prop: "name",
+      label: "供应商类型",
+      required: true,
+      border: true,
+      data: [
+        { label: "贸易商", value: "1" },
+        { label: "工厂", value: "2" },
+      ],
+    },
+    {
+      type: "input",
+      prop: "name",
+      label: "供应商名称",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "address",
+      label: "地址",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "contact",
+      label: "联系信息",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "fileSlot",
+      label: "上传附件",
+    },
+    {
+      type: "input",
+      label: "备注",
+      prop: "remakes",
+      itemType: "textarea",
+    },
+  ];
+});
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/salesReturnDetail/page", sourceList.value.pagination)
+    .then((message) => {
+      console.log(message);
+      sourceList.value.data = message.rows;
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+
+const submitForm = async () => {
+  formDom.value.validate((vaild) => {
+    if (vaild) {
+      const list = formData.data.arrivalDetailList;
+      const total = list.reduce((total, x) => (total += Number(x.count)));
+      if (total < 1) {
+        return ElMessage({
+          message: `本次到货不能为0!`,
+          type: "info",
+        });
+      }
+      let sum = 0;
+      for (let i = 0; i < list.length; i++) {
+        const e = list[i];
+        if (
+          Number(e.sumArrivalCount) + Number(e.count) >=
+          Number(e.purchaseCount)
+        ) {
+          sum += 1;
+        }
+      }
+      formData.data.arrivalStatus = sum === list.length ? "20" : "10";
+      proxy.post("/arrival/add", formData.data).then((res) => {
+        ElMessage({
+          message: `操作成功!`,
+          type: "success",
+        });
+        dialogVisible.value = true;
+        getList();
+      });
+    }
+  });
+};
+
+const getDtl = (row) => {
+  modalType.value = "edit";
+  proxy.post("/productionProcesses/detail", { id: row.id }).then((res) => {
+    formData.data = res;
+    dialogVisible.value = true;
+  });
+};
+
+const handleEdit = (row, status) => {
+  let purchaseStatusName = status == 88 ? "作废" : "终止";
+  const data = { ...row, purchaseStatus: status };
+  // 弹窗提示是否删除
+  ElMessageBox.confirm(
+    `此操作将${purchaseStatusName}该数据, 是否继续?`,
+    "提示",
+    {
+      confirmButtonText: "确定",
+      cancelButtonText: "取消",
+      type: "warning",
+    }
+  ).then(() => {
+    // 删除
+    proxy
+      .post("/purchase/edit", {
+        data,
+      })
+      .then((res) => {
+        ElMessage({
+          message: `${purchaseStatusName}成功`,
+          type: "success",
+        });
+        getList();
+      });
+  });
+};
+
+// 获取供应商数据
+const supplierData = ref([]);
+const getSupplierList = async (req) => {
+  proxy
+    .post("/supplierInfo/page", { pageNum: 1, pageSize: 9999 })
+    .then((res) => {
+      supplierData.value = res.rows;
+    });
+};
+const handleArrival = (row) => {
+  proxy.post("/purchase/detail", { id: row.id }).then((res) => {
+    formData.data = {
+      purchaseId: row.id,
+      code: res.code,
+      supplyId: res.supplyId,
+      arrivalDetailList: res.purchaseDetailList.map((x) => ({
+        ...x,
+        purchaseDetailId: x.id,
+        purchaseCount: x.count,
+        count: 0,
+      })),
+      arrivalStatus: "",
+    };
+    dialogVisible.value = true;
+  });
+};
+
+getList();
+getSupplierList();
+const start = () => {
+  proxy.$router.replace({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      isSubscribe: "40",
+      ids: "",
+    },
+  });
+};
+</script>
+  
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+</style>