Browse Source

供应商模块静态页面

cz 2 years ago
parent
commit
53893f8c4a

+ 497 - 487
src/components/byTable/index.vue

@@ -1,521 +1,531 @@
 <template>
-	<div class="header-actions" v-if="getActionList.length != 0">
-		<div class="overflow-box">
-			<el-button
-				v-for="(item, index) in getActionList"
-				:key="index"
-				:type="item.type || 'primary'"
-        		:plain="item.plain || false"
-				v-bind="getHeaderActions(item)"
-				@click="item.action"
-				:disabled="item.disabled || false"
-			>
-				{{ item.text }}
-			</el-button>
-		</div>
-	</div>
-	<div class="table-list-container by-table">
-		<!-- v-if="!hideHeader" -->
-		<header v-if="false" class="header">
-			<h2>{{ title }}</h2>
-		</header>
-		<div class="by-search" v-if="!hideSearch">
-			<div style="display: flex;">
-				<div class="by-dropdown"  v-for="i in selectConfigCopy" :key="i.prop" style="margin-right:10px">
-					<div class="by-dropdown-title">
-						{{ i.label }}<i class="el-icon-caret-bottom el-icon--right"></i>
-					</div>
-					<ul class="by-dropdown-lists">
-						<li @click="searchItemSelct('all',i)">全部</li>
-						<li v-for="j in i.data" :key="j.value" @click="searchItemSelct(j,i)">{{ j.label }}</li>
-					</ul>
-				</div>
-			</div>
-			
-			<div style="display: flex">
-				<el-input
-					placeholder="请输入关键字"
-					suffix-icon="search"
-					size="mini"
-					v-model="keywrod"
-					@keyup.enter="searchFn"
-				>
-				</el-input>
-				<el-button
-					type="primary"
-					style="margin-left: 10px"
-					size="default"
-					@click="searchFn"
-					>搜索</el-button
-				>
+  <div class="header-actions" v-if="getActionList.length != 0">
+    <div class="overflow-box">
+      <el-button
+        v-for="(item, index) in getActionList"
+        :key="index"
+        :type="item.type || 'primary'"
+        :plain="item.plain || false"
+        v-bind="getHeaderActions(item)"
+        @click="item.action"
+        :disabled="item.disabled || false"
+      >
+        {{ item.text }}
+      </el-button>
+    </div>
+  </div>
+  <div class="table-list-container by-table">
+    <!-- v-if="!hideHeader" -->
+    <header v-if="false" class="header">
+      <h2>{{ title }}</h2>
+    </header>
+    <div class="by-search" v-if="!hideSearch">
+      <div style="display: flex">
+        <div
+          class="by-dropdown"
+          v-for="i in selectConfigCopy"
+          :key="i.prop"
+          style="margin-right: 10px"
+        >
+          <div class="by-dropdown-title">
+            {{ i.label }}<i class="el-icon-caret-bottom el-icon--right"></i>
+          </div>
+          <ul class="by-dropdown-lists">
+            <li
+              @click="searchItemSelct('all', i)"
+              v-if="i.isShowAll === false ? i.isShowAll : true"
+            >
+              全部
+            </li>
+            <li
+              v-for="j in i.data"
+              :key="j.value"
+              @click="searchItemSelct(j, i)"
+            >
+              {{ j.label }}
+            </li>
+          </ul>
+        </div>
+      </div>
 
-				<div class="more-icon"><i class="el-icon-wind-power"></i></div>
-				<div class="more-icon">
-					<i class="el-icon-notebook-2"></i>
-				</div>
-			</div>
-		</div>
+      <div style="display: flex">
+        <el-input
+          placeholder="请输入关键字"
+          suffix-icon="search"
+          size="mini"
+          v-model="keywrod"
+          @keyup.enter="searchFn"
+        >
+        </el-input>
+        <el-button
+          type="primary"
+          style="margin-left: 10px"
+          size="default"
+          @click="searchFn"
+          >搜索</el-button
+        >
 
-		<component :is="containerTag">
-			<div class="filter-form-container">
-				<slot />
-			</div>
+        <div class="more-icon"><i class="el-icon-wind-power"></i></div>
+        <div class="more-icon">
+          <i class="el-icon-notebook-2"></i>
+        </div>
+      </div>
+    </div>
 
-			<el-table
-				ref="hocElTable"
-				v-loading="loading"
-				:data="source"
-				v-if="!hideTable"
-				style="width: 100%"
-				v-bind="$attrs"
-				v-on="tableEvents"
-				row-key="id"
-				:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
-			>
-				<el-table-column
-					v-for="(item, index) in config"
-					:key="index"
-					v-bind="getAttrsValue(item)"
-					:type="item.type || ''"
-				>
-					
-					
-					<template #default="scope" v-if="!item.type">
-						<slot :name="item.attrs.slot" :item="scope.row"  v-if="item.attrs.slot">
-							插槽占位符
-						</slot>
-						<div v-else-if="isFunction(getValue(scope, item))">
-							
+    <component :is="containerTag">
+      <div class="filter-form-container">
+        <slot />
+      </div>
 
-							<component
-								:is="
-									renderTypeList[getMatchRenderFunction(item)]
-										.target
-								"
-								:cell-list="getValue(scope, item)()"
-								:row="scope.row"
-								:parent="getParent"
-								@click="
-									($event) => {
-										handleNativeClick(
-											getAttrsValue(item),
-											$event,
-											item
-										)
-									}
-								"
-							/>
-						</div>
-						<div v-else>
-							{{ getValue(scope, item) }}
-						</div>
-					</template>
-				</el-table-column>
-			</el-table>
+      <el-table
+        ref="hocElTable"
+        v-loading="loading"
+        :data="source"
+        v-if="!hideTable"
+        style="width: 100%"
+        v-bind="$attrs"
+        v-on="tableEvents"
+        row-key="id"
+        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+      >
+        <el-table-column
+          v-for="(item, index) in config"
+          :key="index"
+          v-bind="getAttrsValue(item)"
+          :type="item.type || ''"
+        >
+          <template #default="scope" v-if="!item.type">
+            <slot
+              :name="item.attrs.slot"
+              :item="scope.row"
+              v-if="item.attrs.slot"
+            >
+              插槽占位符
+            </slot>
+            <div v-else-if="isFunction(getValue(scope, item))">
+              <component
+                :is="renderTypeList[getMatchRenderFunction(item)].target"
+                :cell-list="getValue(scope, item)()"
+                :row="scope.row"
+                :parent="getParent"
+                @click="
+                  ($event) => {
+                    handleNativeClick(getAttrsValue(item), $event, item);
+                  }
+                "
+              />
+            </div>
+            <div v-else>
+              {{ getValue(scope, item) }}
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
 
-			<el-row
-				v-if="!hidePagination"
-				class="table-pagination"
-				justify="end"
-				type="flex"
-			>
-				<el-pagination
-					background
-					layout="total, sizes, prev, pager, next, jumper"
-					:current-page="getPagination.pageNum"
-					:page-size="getPagination.pageSize"
-					:total="getPagination.total"
-					@size-change="handleSizeChange"
-					@current-change="handlePageChange"
-				/>
-			</el-row>
-		</component>
-	</div>
+      <el-row
+        v-if="!hidePagination"
+        class="table-pagination"
+        justify="end"
+        type="flex"
+      >
+        <el-pagination
+          background
+          layout="total, sizes, prev, pager, next, jumper"
+          :current-page="getPagination.pageNum"
+          :page-size="getPagination.pageSize"
+          :total="getPagination.total"
+          @size-change="handleSizeChange"
+          @current-change="handlePageChange"
+        />
+      </el-row>
+    </component>
+  </div>
 </template>
   
   <script>
-import { isFunction as isFn, isBoolean } from './type'
-import ElementsMapping from './ElementsMapping'
-import ComponentsMapping from './ComponentsMapping'
-import { computed, defineComponent, getCurrentInstance, ref } from 'vue'
-import expand from './expand'
+import { isFunction as isFn, isBoolean } from "./type";
+import ElementsMapping from "./ElementsMapping";
+import ComponentsMapping from "./ComponentsMapping";
+import { computed, defineComponent, getCurrentInstance, ref } from "vue";
+import expand from "./expand";
 export default defineComponent({
-	name: 'Table',
-	components: {
-		ElementsMapping,
-		ComponentsMapping,
-	},
-	props: {
-		hideSearch: {
-			type: Boolean,
-			default: false,
-		},
-		hideTable: {
-			type: Boolean, 
-			default: false,
-		},
-		//顶部搜索下拉配置
-		selectConfig:{
-			type: Array,
-			default() {
-				return []
-			},
-		},
-		// 获取表格元数据时携带的参数
-		filterParams: {
-			type: Object,
-			default() {
-				return {}
-			},
-		},
-		// 表格加载 loading
-		loading: {
-			type: Boolean,
-			default: false,
-		},
-		// 表格名称
-		title: {
-			type: String,
-			default: '',
-		},
-		// 表格元数据
-		source: {
-			type: Array,
-			required: true,
-			default() {
-				return []
-			},
-		},
-		searchConfig: {
-			type: Object,
-			default() {
-				return {
-					keyword: '',
-				}
-			},
-		},
-		// 指定外层容器的渲染组件
-		containerTag: {
-			type: String,
-			default: 'div',
-		},
-		// 是否隐藏表头
-		hideHeader: {
-			type: Boolean,
-			default: false,
-		},
-		// 是否隐藏分页
-		hidePagination: {
-			type: Boolean,
-			default: false,
-		},
-		// 分页配置
-		pagination: {
-			type: Object,
-			default() {
-				return {}
-			},
-		},
-		// 表格配置文件
-		config: {
-			type: Array,
-			default() {
-				return []
-			},
-		},
-		// 表头右上方的按钮组
-		actionList: {
-			type: Array,
-			default() {
-				return [{ text: '', action: () => {} }]
-			},
-		},
-		// element table 原生事件
-		tableEvents: {
-			type: Object,
-			default() {
-				return {}
-			},
-		},
-		searchKey: {
-			type: String,
-			default: 'keyword',
-		},
-	},
-	setup(props) {
-		
-		const { proxy } = getCurrentInstance()
-		const keywrod = ref('')
-		const selectConfigCopy = computed(()=>{
-			return props.selectConfig.map((item)=>{
-				item.labelCopy = item.label
-				return item
-			})
-			 
-		})
-		console.log(selectConfigCopy)
-		const getAttrsValue = (item) => {
-			const { attrs } = item
-			const result = {
-				...attrs,
-			}
-			delete result.prop
-			return result
-		}
-		const renderTypeList = ref({
-			render: {},
-			renderHTML: {
-				target: 'elements-mapping',
-			},
-			renderComponent: {
-				target: 'components-mapping',
-			},
-		})
-		const getParent = computed(() => {
-			return proxy.$parent
-		})
-		const getPagination = computed(() => {
-			const params = {
-				pageNum: 1,
-				pageSize: 10,
-				total: 0,
-			}
-			return Object.assign({}, params, props.pagination)
-		})
-		const getActionList = computed(() => {
-			return props.actionList
-				.slice()
-				.reverse()
-				.filter((it) => it.text)
-		})
-		const getValue = (scope, configItem) => {
-			const prop = configItem.attrs.prop
-			const renderName = getMatchRenderFunction(configItem)
-			const renderObj = renderTypeList.value[renderName]
-			if (renderObj && isFunction(configItem[renderName])) {
-				return renderObj.target
-					? getRenderValue(scope, configItem, {
-							name: renderName,
-							type: 'bind',
-					  })
-					: getRenderValue(scope, configItem)
-			}
-			return scope.row[prop]
-		}
-		const getRenderValue = (
-			scope,
-			item,
-			fn = { name: 'render', type: 'call' }
-		) => {
-			const prop = item.attrs.prop
-			const propValue = prop && scope.row[prop]
-			scope.row.$index = scope.$index
-			const args = propValue !== undefined ? propValue : scope.row
-			
-			return item[fn.name][fn.type](getParent.value, args)
-		}
-		// 匹配 render 开头的函数
-		const getMatchRenderFunction = (obj) => {
-			return Object.keys(obj).find((key) => {
-				const matchRender = key.match(/^render.*/)
-				return matchRender && matchRender[0]
-			})
-		}
-		const isFunction = (fn) => {
-			return isFn(fn)
-		}
-		const searchFn = (val) => {
-			console.log(props)
-			proxy.$emit(
-				'getList',
-				Object.assign(props.filterParams, { [props.searchKey]: keywrod.value })
-			)
-		}
-		const handlePageChange = (val) => {
-			proxy.$emit(
-				'getList',
-				Object.assign(props.filterParams, { pageNum: val })
-			)
-		}
-		const handleSizeChange = (val) => {
-			proxy.$emit(
-				'getList',
-				Object.assign(props.filterParams, { pageSize: val })
-			)
-		}
-		const getHeaderActions = (item) => {
-			return {
-				...item.attrs,
-			}
-		}
-		const stopBubbles = (e) => {
-			const event = e || window.event
-			if (event && event.stopPropagation) {
-				event.stopPropagation()
-			} else {
-				event.cancelBubble = true
-			}
-		}
-		const handleNativeClick = ({ isBubble }, e,item) => {
-			// 考虑到单元格内渲染了组件,并且组件自身可能含有点击事件,故添加了阻止冒泡机制
-			// 若指定 isBubble 为 false,则当前单元格恢复冒泡机制
-			if (isBoolean(isBubble) && !isBubble) return
-			stopBubbles(e)
-		}
-		//下拉搜索相关
-		
-		const searchItemSelct = ((item,i) => {
-			if(item == 'all') {
-				i.label = '全部'
-				proxy.$emit(
-					'getList',
-					Object.assign(props.filterParams, { [i.prop]: '' })
-				)
-				return
-			}
-			i.label = item.label
-			console.log(item,i)
-			proxy.$emit(
-				'getList',
-				Object.assign(props.filterParams, { [i.prop]: item.value })
-			)
-		})
-		return {
-			getParent,
-			getPagination,
-			renderTypeList,
-			getActionList,
-			getAttrsValue,
-			getValue,
-			getRenderValue,
-			getMatchRenderFunction,
-			isFunction,
-			handlePageChange,
-			handleSizeChange,
-			getHeaderActions,
-			stopBubbles,
-			handleNativeClick,
-			keywrod,
-			searchFn,
-			searchItemSelct,
-			selectConfigCopy
-		}
-	},
-})
+  name: "Table",
+  components: {
+    ElementsMapping,
+    ComponentsMapping,
+  },
+  props: {
+    hideSearch: {
+      type: Boolean,
+      default: false,
+    },
+    hideTable: {
+      type: Boolean,
+      default: false,
+    },
+    //顶部搜索下拉配置
+    selectConfig: {
+      type: Array,
+      default() {
+        return [];
+      },
+    },
+    // 获取表格元数据时携带的参数
+    filterParams: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+    // 表格加载 loading
+    loading: {
+      type: Boolean,
+      default: false,
+    },
+    // 表格名称
+    title: {
+      type: String,
+      default: "",
+    },
+    // 表格元数据
+    source: {
+      type: Array,
+      required: true,
+      default() {
+        return [];
+      },
+    },
+    searchConfig: {
+      type: Object,
+      default() {
+        return {
+          keyword: "",
+        };
+      },
+    },
+    // 指定外层容器的渲染组件
+    containerTag: {
+      type: String,
+      default: "div",
+    },
+    // 是否隐藏表头
+    hideHeader: {
+      type: Boolean,
+      default: false,
+    },
+    // 是否隐藏分页
+    hidePagination: {
+      type: Boolean,
+      default: false,
+    },
+    // 分页配置
+    pagination: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+    // 表格配置文件
+    config: {
+      type: Array,
+      default() {
+        return [];
+      },
+    },
+    // 表头右上方的按钮组
+    actionList: {
+      type: Array,
+      default() {
+        return [{ text: "", action: () => {} }];
+      },
+    },
+    // element table 原生事件
+    tableEvents: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+    searchKey: {
+      type: String,
+      default: "keyword",
+    },
+    // 是否显示过滤的全部选项
+    // isShowAll: {
+    //   type: Boolean,
+    //   default: true,
+    // },
+  },
+  setup(props) {
+    const { proxy } = getCurrentInstance();
+    const keywrod = ref("");
+    const selectConfigCopy = computed(() => {
+      return props.selectConfig.map((item) => {
+        item.labelCopy = item.label;
+        return item;
+      });
+    });
+    console.log(selectConfigCopy);
+    const getAttrsValue = (item) => {
+      const { attrs } = item;
+      const result = {
+        ...attrs,
+      };
+      delete result.prop;
+      return result;
+    };
+    const renderTypeList = ref({
+      render: {},
+      renderHTML: {
+        target: "elements-mapping",
+      },
+      renderComponent: {
+        target: "components-mapping",
+      },
+    });
+    const getParent = computed(() => {
+      return proxy.$parent;
+    });
+    const getPagination = computed(() => {
+      const params = {
+        pageNum: 1,
+        pageSize: 10,
+        total: 0,
+      };
+      return Object.assign({}, params, props.pagination);
+    });
+    const getActionList = computed(() => {
+      return props.actionList
+        .slice()
+        .reverse()
+        .filter((it) => it.text);
+    });
+    const getValue = (scope, configItem) => {
+      const prop = configItem.attrs.prop;
+      const renderName = getMatchRenderFunction(configItem);
+      const renderObj = renderTypeList.value[renderName];
+      if (renderObj && isFunction(configItem[renderName])) {
+        return renderObj.target
+          ? getRenderValue(scope, configItem, {
+              name: renderName,
+              type: "bind",
+            })
+          : getRenderValue(scope, configItem);
+      }
+      return scope.row[prop];
+    };
+    const getRenderValue = (
+      scope,
+      item,
+      fn = { name: "render", type: "call" }
+    ) => {
+      const prop = item.attrs.prop;
+      const propValue = prop && scope.row[prop];
+      scope.row.$index = scope.$index;
+      const args = propValue !== undefined ? propValue : scope.row;
+
+      return item[fn.name][fn.type](getParent.value, args);
+    };
+    // 匹配 render 开头的函数
+    const getMatchRenderFunction = (obj) => {
+      return Object.keys(obj).find((key) => {
+        const matchRender = key.match(/^render.*/);
+        return matchRender && matchRender[0];
+      });
+    };
+    const isFunction = (fn) => {
+      return isFn(fn);
+    };
+    const searchFn = (val) => {
+      console.log(props);
+      proxy.$emit(
+        "getList",
+        Object.assign(props.filterParams, { [props.searchKey]: keywrod.value })
+      );
+    };
+    const handlePageChange = (val) => {
+      proxy.$emit(
+        "getList",
+        Object.assign(props.filterParams, { pageNum: val })
+      );
+    };
+    const handleSizeChange = (val) => {
+      proxy.$emit(
+        "getList",
+        Object.assign(props.filterParams, { pageSize: val })
+      );
+    };
+    const getHeaderActions = (item) => {
+      return {
+        ...item.attrs,
+      };
+    };
+    const stopBubbles = (e) => {
+      const event = e || window.event;
+      if (event && event.stopPropagation) {
+        event.stopPropagation();
+      } else {
+        event.cancelBubble = true;
+      }
+    };
+    const handleNativeClick = ({ isBubble }, e, item) => {
+      // 考虑到单元格内渲染了组件,并且组件自身可能含有点击事件,故添加了阻止冒泡机制
+      // 若指定 isBubble 为 false,则当前单元格恢复冒泡机制
+      if (isBoolean(isBubble) && !isBubble) return;
+      stopBubbles(e);
+    };
+    //下拉搜索相关
+
+    const searchItemSelct = (item, i) => {
+      if (item == "all") {
+        i.label = "全部";
+        proxy.$emit(
+          "getList",
+          Object.assign(props.filterParams, { [i.prop]: "" })
+        );
+        return;
+      }
+      i.label = item.label;
+      console.log(item, i);
+      proxy.$emit(
+        "getList",
+        Object.assign(props.filterParams, { [i.prop]: item.value })
+      );
+    };
+
+    return {
+      getParent,
+      getPagination,
+      renderTypeList,
+      getActionList,
+      getAttrsValue,
+      getValue,
+      getRenderValue,
+      getMatchRenderFunction,
+      isFunction,
+      handlePageChange,
+      handleSizeChange,
+      getHeaderActions,
+      stopBubbles,
+      handleNativeClick,
+      keywrod,
+      searchFn,
+      searchItemSelct,
+      selectConfigCopy,
+    };
+  },
+});
 </script>
   <style>
 .table-list-container th {
-	color: #333 !important;
+  color: #333 !important;
 }
-.by-table td .el-button+.el-button{
-	margin-left: 0!important;
+.by-table td .el-button + .el-button {
+  margin-left: 0 !important;
 }
-.by-table td .el-button{
-	background: none!important;
-	margin: 0!important;
-	padding:8px 6px!important;
+.by-table td .el-button {
+  background: none !important;
+  margin: 0 !important;
+  padding: 8px 6px !important;
 }
 </style>
   <style lang="scss" scoped>
 .by-search {
-	display: flex;
-	justify-content: space-between;
-	margin-bottom: 10px;
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 10px;
 }
 .by-dropdown {
-	width: 106px;
-	position: relative;
-	text-align: left;
-	height: 32px;
-	z-index: 100;
-	padding:0 10px;
-	transition: all 0.5s ease;
-	cursor: pointer;
-	line-height: 32px;
-	.by-dropdown-title {
-		font-size: 14px;
-		background-color: #fff;
-		
-	}
-	ul {
-		position: absolute;
-		left: 0;
-		right: 0;
-		top: 32px;
-		padding: 0;
-		margin: 0;
-		z-index: 100;
-		display: none;
-		li {
-			list-style: none;
-			font-size: 12px;
-			height: 30px;
-			padding: 0 10px;
-		}
-		li:hover {
-			background-color: #eff6ff;
-			color: #0084ff;
-		}
-	}
+  width: 106px;
+  position: relative;
+  text-align: left;
+  height: 32px;
+  z-index: 100;
+  padding: 0 10px;
+  transition: all 0.5s ease;
+  cursor: pointer;
+  line-height: 32px;
+  .by-dropdown-title {
+    font-size: 14px;
+    background-color: #fff;
+  }
+  ul {
+    position: absolute;
+    left: 0;
+    right: 0;
+    top: 32px;
+    padding: 0;
+    margin: 0;
+    z-index: 100;
+    display: none;
+    li {
+      list-style: none;
+      font-size: 12px;
+      height: 30px;
+      padding: 0 10px;
+    }
+    li:hover {
+      background-color: #eff6ff;
+      color: #0084ff;
+    }
+  }
 }
 
 .by-dropdown::before {
-	display: block;
-	width: 1px;
-	content: ' ';
-	position: absolute;
-	height: 14px;
-	top: 8px;
-	background-color: #ddd;
-	right: 0;
-	z-index: 101;
-
+  display: block;
+  width: 1px;
+  content: " ";
+  position: absolute;
+  height: 14px;
+  top: 8px;
+  background-color: #ddd;
+  right: 0;
+  z-index: 101;
 }
 
 .by-dropdown:hover {
-	background: #ffffff;
-	
-	border-radius: 2px 2px 2px 2px;
-	opacity: 1;
-	ul {
-		background: #ffffff;
-		box-shadow: 0px 2px 16px 1px rgba(0, 0, 0, 0.06);
-		border-radius: 2px 2px 2px 2px;
-		opacity: 1;
-		display: block;
-		text-align: left;
-	}
+  background: #ffffff;
+
+  border-radius: 2px 2px 2px 2px;
+  opacity: 1;
+  ul {
+    background: #ffffff;
+    box-shadow: 0px 2px 16px 1px rgba(0, 0, 0, 0.06);
+    border-radius: 2px 2px 2px 2px;
+    opacity: 1;
+    display: block;
+    text-align: left;
+  }
 }
 .header-actions {
-	flex: 1;
-	overflow-x: auto;
-	padding: 20px;
-	background: #fff;
+  flex: 1;
+  overflow-x: auto;
+  padding: 20px;
+  background: #fff;
   margin-bottom: 20px;
-	.overflow-box {
-		
-		:deep() .el-button:nth-child(1) {
-			margin-left: 10px;
-		}
-	}
+  .overflow-box {
+    :deep() .el-button:nth-child(1) {
+      margin-left: 10px;
+    }
+  }
 }
 .table-list-container {
-	background: #fff;
-	padding: 13px 20px 20px;
-	.table-pagination {
-		padding-top: 20px;
-	}
-	.header {
-		display: flex;
-		padding-bottom: 20px;
-	}
-	.el-table {
-		:deep() th {
-			font-size: 14px;
-		}
-		:deep() td {
-			font-size: 14px;
-		}
-	}
+  background: #fff;
+  padding: 13px 20px 20px;
+  .table-pagination {
+    padding-top: 20px;
+  }
+  .header {
+    display: flex;
+    padding-bottom: 20px;
+  }
+  .el-table {
+    :deep() th {
+      font-size: 14px;
+    }
+    :deep() td {
+      font-size: 14px;
+    }
+  }
 }
 </style>

+ 373 - 0
src/components/product/SelectGoods.vue

@@ -0,0 +1,373 @@
+<template>
+  <div>
+    <byTable
+      ref="table"
+      :source="sourceList.data"
+      :pagination="sourceList.pagination"
+      :config="config"
+      :loading="loading"
+      highlight-current-row
+      :selectConfig="selectConfig"
+      :table-events="{
+        //element talbe事件都能传
+        select: select,
+      }"
+      :action-list="[]"
+      @get-list="getList"
+    >
+    </byTable>
+    <div>
+      <div>已选择货品</div>
+      <div style="margin: 10px 0px">
+        <el-tag
+          style="margin-right: 10px"
+          type="info"
+          closable
+          v-for="(good, index) in goodList"
+          :key="good.id"
+          @close="handleRemove(index)"
+          >{{ good.name }}</el-tag
+        >
+      </div>
+      <div style="text-align: center">
+        <el-button @click="handleCancel">取消</el-button>
+        <el-button type="primary" @click="handleSubmit"> 确 定 </el-button>
+      </div>
+    </div>
+  </div>
+</template>
+  
+<script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import treeList from "@/components/product/treeList";
+import { computed, defineComponent, ref, watch } from "vue";
+const loading = ref(false);
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+    type: "",
+    productClassifyId: "",
+    keyword: "",
+    definition: "1",
+  },
+});
+let dialogVisible = ref(false);
+let openExcelDialog = ref(false);
+
+let modalType = ref("add");
+let rules = ref({
+  productClassifyId: [
+    { required: true, message: "请选择产品分类", trigger: "change" },
+  ],
+  type: [{ required: true, message: "请选择产品类型", trigger: "change" }],
+  name: [{ required: true, message: "请输入产品名称", trigger: "blur" }],
+  unit: [{ required: true, message: "请选择单位", trigger: "change" }],
+});
+const { proxy } = getCurrentInstance();
+const selectConfig = reactive([
+  {
+    label: "物品类型",
+    prop: "definition",
+    isShowAll: false, //不显示全部搜索
+    data: [
+      {
+        label: "产品",
+        value: "1",
+      },
+      {
+        label: "物料",
+        value: "2",
+      },
+    ],
+  },
+  {
+    label: "所属分类",
+    prop: "productClassifyId",
+    data: [],
+  },
+]);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "货品类型",
+        prop: "type",
+      },
+      render(type) {
+        return sourceList.value.pagination.definition == 1 ? "产品" : "物料";
+      },
+    },
+    {
+      attrs: {
+        label: "所属分类",
+        prop: "",
+      },
+      render(type) {
+        return sourceList.value.pagination.definition == 1 ? "产品" : "物料";
+      },
+    },
+    {
+      attrs: {
+        label: "货品编码",
+        prop: "code",
+      },
+    },
+    {
+      attrs: {
+        label: "货品名称",
+        prop: "name",
+      },
+    },
+
+    {
+      attrs: {
+        label: "规格型号",
+        prop: "spec",
+      },
+    },
+    {
+      attrs: {
+        label: "单位",
+        prop: "unit",
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: "100",
+        align: "right",
+      },
+      // 渲染 el-button,一般用在最后一列。
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "选择",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              handleSelect(row);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+
+let formData = reactive({
+  data: {},
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const byform = ref(null);
+const treeListData = ref([]);
+const formConfig = computed(() => {
+  return [
+    {
+      type: "treeSelect",
+      prop: "productClassifyId",
+      label: "产品分类",
+      data: [],
+    },
+    {
+      type: "select",
+      prop: "type",
+      label: "产品类型",
+      required: true,
+      data: [
+        {
+          label: "成品",
+          id: "1",
+        },
+        {
+          label: "半成品",
+          id: "2",
+        },
+      ],
+    },
+    {
+      type: "input",
+      prop: "name",
+      label: "产品名称",
+    },
+    {
+      type: "input",
+      prop: "spec",
+      label: "规格型号",
+    },
+    {
+      type: "select",
+      prop: "unit",
+      label: "单位",
+      required: true,
+      data: [
+        {
+          label: "个",
+          id: "个",
+        },
+        {
+          label: "双",
+          id: "双",
+        },
+      ],
+    },
+    {
+      type: "slot",
+      slotName: "productPic",
+      prop: "fileList",
+      label: "产品图片",
+    },
+    {
+      type: "input",
+      prop: "remark",
+      label: "备注",
+      itemType: "textarea",
+    },
+  ];
+});
+
+const lastDefinition = ref("");
+const getList = async (req = {}) => {
+  for (const key in req) {
+    sourceList.value.pagination[key] = req[key];
+    if (key === "definition") {
+      if (lastDefinition.value !== req[key]) {
+        getTreeList();
+        lastDefinition.value = req[key];
+        // 如果选择的物品分类不一致,则分类默认选中全部
+        return table.value.searchItemSelct("all", selectConfig[1]);
+      }
+    }
+  }
+  sourceList.value.pagination = {
+    ...sourceList.value.pagination,
+    ...req,
+  };
+  loading.value = true;
+  proxy
+    .post("/productInfo/page", sourceList.value.pagination)
+    .then((message) => {
+      sourceList.value.data = message.rows.map((x) => ({ ...x, fileList: [] }));
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+
+      const productIdList = message.rows.map((x) => x.id);
+      // 请求文件数据并回显
+      if (productIdList.length > 0) {
+        proxy
+          .post("/fileInfo/getList", { businessIdList: productIdList })
+          .then((fileObj) => {
+            for (let i = 0; i < sourceList.value.data.length; i++) {
+              const e = sourceList.value.data[i];
+              for (const key in fileObj) {
+                if (e.id === key) {
+                  e.fileList = fileObj[key];
+                }
+              }
+            }
+          });
+      }
+    });
+};
+
+const getTreeList = () => {
+  proxy
+    .post("/productClassify/tree", {
+      parentId: "",
+      name: "",
+      definition: sourceList.value.pagination.definition,
+    })
+    .then((message) => {
+      selectConfig[1].data = message.map((x) => ({
+        label: x.label,
+        value: x.id,
+      }));
+    });
+};
+
+const goodList = ref([]);
+const handleSelect = (row) => {
+  const flag = goodList.value.some((x) => x.id === row.id);
+  if (flag)
+    return ElMessage({
+      message: "该产品已选择",
+      type: "info",
+    });
+  goodList.value.push(row);
+  return ElMessage({
+    message: "选择成功",
+    type: "success",
+  });
+};
+
+const handleRemove = (index) => {
+  goodList.value.splice(index, 1);
+  return ElMessage({
+    message: "删除成功",
+    type: "success",
+  });
+};
+
+const handleSubmit = () => {
+  if (!goodList.value.length > 0)
+    return ElMessage({
+      message: "请添加货品",
+      type: "info",
+    });
+  proxy.$emit("pushGoods", goodList.value);
+  goodList.value = [];
+};
+
+const handleCancel = () => {
+  goodList.value = [];
+  proxy.$emit("cancel");
+};
+
+const table = ref(null);
+
+const searchItemSelct = () => {
+  // 默认选中的方法
+  table.value.searchItemSelct(selectConfig[0].data[0], selectConfig[0]);
+};
+
+onMounted(() => {
+  searchItemSelct();
+});
+</script>
+  
+<style lang="scss" scoped>
+.user {
+  padding: 20px;
+  display: flex;
+  justify-content: space-between;
+  .tree {
+    width: 300px;
+  }
+  .content {
+    width: calc(100% - 320px);
+  }
+}
+.pic {
+  object-fit: contain;
+  width: 50px;
+  height: 50px;
+  cursor: pointer;
+  vertical-align: middle;
+}
+</style>

+ 12 - 10
src/components/product/SelectMaterial.vue

@@ -358,18 +358,20 @@ const getList = async (req) => {
 
       const productIdList = message.rows.map((x) => x.id);
       // 请求文件数据并回显
-      proxy
-        .post("/fileInfo/getList", { businessIdList: productIdList })
-        .then((fileObj) => {
-          for (let i = 0; i < sourceList.value.data.length; i++) {
-            const e = sourceList.value.data[i];
-            for (const key in fileObj) {
-              if (e.id === key) {
-                e.fileList = fileObj[key];
+      if (productIdList.length > 0) {
+        proxy
+          .post("/fileInfo/getList", { businessIdList: productIdList })
+          .then((fileObj) => {
+            for (let i = 0; i < sourceList.value.data.length; i++) {
+              const e = sourceList.value.data[i];
+              for (const key in fileObj) {
+                if (e.id === key) {
+                  e.fileList = fileObj[key];
+                }
               }
             }
-          }
-        });
+          });
+      }
     });
 };
 const uploadData = ref({});

+ 12 - 10
src/components/product/SelectProduct.vue

@@ -337,18 +337,20 @@ const getList = async (req) => {
 
       const productIdList = message.rows.map((x) => x.id);
       // 请求文件数据并回显
-      proxy
-        .post("/fileInfo/getList", { businessIdList: productIdList })
-        .then((fileObj) => {
-          for (let i = 0; i < sourceList.value.data.length; i++) {
-            const e = sourceList.value.data[i];
-            for (const key in fileObj) {
-              if (e.id === key) {
-                e.fileList = fileObj[key];
+      if (productIdList.length > 0) {
+        proxy
+          .post("/fileInfo/getList", { businessIdList: productIdList })
+          .then((fileObj) => {
+            for (let i = 0; i < sourceList.value.data.length; i++) {
+              const e = sourceList.value.data[i];
+              for (const key in fileObj) {
+                if (e.id === key) {
+                  e.fileList = fileObj[key];
+                }
               }
             }
-          }
-        });
+          });
+      }
     });
 };
 

+ 227 - 223
src/views/process/processApproval.vue

@@ -1,238 +1,242 @@
 <template>
-    <div class="processApproval">
-        <div class="left-card">
-            <div class="commons-title title">
-                流程标题
-            </div>
-            <div class="">
-                <p>流程内容</p>
-                <p>流程内容</p>
-                <p>流程内容</p>
-                <p>流程内容</p>
-                <p>流程内容</p>
-                <p>流程内容</p>
-                <p>流程内容</p>
-                <p>流程内容</p>
-            </div>
-        </div>
-        <div class="right-card">
-            <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
-                <el-tab-pane label="审批记录" name="first">
-                    <ul class="flow-chart">
-                        <li>
-                            <div class="left-icon">
-                                <i class="iconfont icon-iconm_daick"></i>
-                                <i class="iconfont icon-iconm_daohzj  right-btm-status"></i>
-                            </div>
-                            <div class="right-conetnt">
-                                <div class="name">
-                                    发起人:张三
-                                    <span>2022-11-11 00:00:00</span>
-                                </div>
-                                
-                                <div class="remark">
-                                    <div class="label">
-                                        发起审批
-                                        
-                                    </div>
-                                    1231231231231321231
-                                </div>
-                            </div>
-                            <div class="line"></div>
-                        </li>
-                        <li>
-                            <div class="left-icon">
-                                <i class="iconfont icon-iconm_daick"></i>
-                                <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
-                            </div>
-                            <div class="right-conetnt">
-                                <div class="name">
-                                    发起人:张三
-                                    <span>2022-11-11 00:00:00</span>
-                                </div>
-                                
-                                <div class="remark">
-                                    <div class="label">
-                                        发起审批
-                                    </div>
-                                    
-                                    <div>啊圣诞快乐家里快速打击啊老师的煎熬老师的煎熬上来看大家速度快垃圾上单绿卡数据的卡拉数据的卡拉设计的拉开时间</div>
-                                </div>
-                            </div>
-                            <div class="line"></div>
-                        </li>
-                        <li>
-                            <div class="left-icon">
-                                <i class="iconfont icon-iconm_daick"></i>
-                                <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
-                            </div>
-                            <div class="right-conetnt">
-                                <div class="name">
-                                    发起人:张三
-                                    <span>2022-11-11 00:00:00</span>
-                                </div>
-                                
-                                <div class="remark">
-                                    <div class="label">
-                                        发起审批
-                                    </div>
-                                    
-                                    <div>啊圣诞快乐家里快速打击啊老师的煎熬老师的煎熬上来看大家速度快垃圾上单绿卡数据的卡拉数据的卡拉设计的拉开时间</div>
-                                </div>
-                            </div>
-                            <div class="line"></div>
-                        </li>
-                        <li>
-                            <div class="left-icon">
-                                <i class="iconfont icon-iconm_daick"></i>
-                                <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
-                            </div>
-                            <div class="right-conetnt">
-                                <div class="name">
-                                    发起人:张三
-                                    <span>2022-11-11 00:00:00</span>
-                                </div>
-                                
-                                <div class="remark">
-                                    <div class="label">
-                                        发起审批
-                                    </div>
-                                    
-                                    <div>啊圣诞快乐家里快速打击啊老师的煎熬老师的煎熬上来看大家速度快垃圾上单绿卡数据的卡拉数据的卡拉设计的拉开时间</div>
-                                </div>
-                            </div>
-                            <div class="line"></div>
-                        </li>
-                        <li>
-                            <div class="left-icon">
-                                <i class="iconfont icon-iconm_daick"></i>
-                                <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
-                            </div>
-                            <div class="right-conetnt">
-                                <div class="name">
-                                    发起人:张三
-                                    <span>2022-11-11 00:00:00</span>
-                                </div>
-                                
-                                <div class="remark">
-                                    <div class="label">
-                                        发起审批
-                                    </div>
-                                    
-                                    <div>啊圣诞快乐家里快速打击啊老师的煎熬老师的煎熬上来看大家速度快垃圾上单绿卡数据的卡拉数据的卡拉设计的拉开时间</div>
-                                </div>
-                            </div>
-                            <div class="line"></div>
-                        </li>
-                    </ul>
-                </el-tab-pane>
-                <el-tab-pane label="决策辅助" name="second">决策辅助</el-tab-pane>
-            </el-tabs>
-        </div>
+  <div class="processApproval">
+    <div class="left-card">
+      <div class="commons-title title">流程标题</div>
+      <div class="">
+        <p>流程内容</p>
+        <p>流程内容</p>
+        <p>流程内容</p>
+        <p>流程内容</p>
+        <p>流程内容</p>
+        <p>流程内容</p>
+        <p>流程内容</p>
+        <p>流程内容</p>
+      </div>
     </div>
+    <div class="right-card">
+      <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+        <el-tab-pane label="审批记录" name="first">
+          <ul class="flow-chart">
+            <li>
+              <div class="left-icon">
+                <i class="iconfont icon-iconm_daick"></i>
+                <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
+              </div>
+              <div class="right-conetnt">
+                <div class="name">
+                  发起人:张三
+                  <span>2022-11-11 00:00:00</span>
+                </div>
+
+                <div class="remark">
+                  <div class="label">发起审批</div>
+                  1231231231231321231
+                </div>
+              </div>
+              <div class="line"></div>
+            </li>
+            <li>
+              <div class="left-icon">
+                <i class="iconfont icon-iconm_daick"></i>
+                <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
+              </div>
+              <div class="right-conetnt">
+                <div class="name">
+                  发起人:张三
+                  <span>2022-11-11 00:00:00</span>
+                </div>
+
+                <div class="remark">
+                  <div class="label">发起审批</div>
+
+                  <div>
+                    啊圣诞快乐家里快速打击啊老师的煎熬老师的煎熬上来看大家速度快垃圾上单绿卡数据的卡拉数据的卡拉设计的拉开时间
+                  </div>
+                </div>
+              </div>
+              <div class="line"></div>
+            </li>
+            <li>
+              <div class="left-icon">
+                <i class="iconfont icon-iconm_daick"></i>
+                <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
+              </div>
+              <div class="right-conetnt">
+                <div class="name">
+                  发起人:张三
+                  <span>2022-11-11 00:00:00</span>
+                </div>
+
+                <div class="remark">
+                  <div class="label">发起审批</div>
+
+                  <div>
+                    啊圣诞快乐家里快速打击啊老师的煎熬老师的煎熬上来看大家速度快垃圾上单绿卡数据的卡拉数据的卡拉设计的拉开时间
+                  </div>
+                </div>
+              </div>
+              <div class="line"></div>
+            </li>
+            <li>
+              <div class="left-icon">
+                <i class="iconfont icon-iconm_daick"></i>
+                <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
+              </div>
+              <div class="right-conetnt">
+                <div class="name">
+                  发起人:张三
+                  <span>2022-11-11 00:00:00</span>
+                </div>
+
+                <div class="remark">
+                  <div class="label">发起审批</div>
+
+                  <div>
+                    啊圣诞快乐家里快速打击啊老师的煎熬老师的煎熬上来看大家速度快垃圾上单绿卡数据的卡拉数据的卡拉设计的拉开时间
+                  </div>
+                </div>
+              </div>
+              <div class="line"></div>
+            </li>
+            <li>
+              <div class="left-icon">
+                <i class="iconfont icon-iconm_daick"></i>
+                <i class="iconfont icon-iconm_daohzj right-btm-status"></i>
+              </div>
+              <div class="right-conetnt">
+                <div class="name">
+                  发起人:张三
+                  <span>2022-11-11 00:00:00</span>
+                </div>
+
+                <div class="remark">
+                  <div class="label">发起审批</div>
+
+                  <div>
+                    啊圣诞快乐家里快速打击啊老师的煎熬老师的煎熬上来看大家速度快垃圾上单绿卡数据的卡拉数据的卡拉设计的拉开时间
+                  </div>
+                </div>
+              </div>
+              <div class="line"></div>
+            </li>
+          </ul>
+        </el-tab-pane>
+        <el-tab-pane label="决策辅助" name="second">决策辅助</el-tab-pane>
+      </el-tabs>
+    </div>
+  </div>
 </template>
 <style lang="scss" scoped>
 .processApproval {
-    display: flex;
-    justify-content: space-between;
-    margin-top:20px;
-    padding: 0 20px;
-    .left-card{
-        background: #FFF;
-        border-radius: 4px;
-        padding: 20px;
-        flex:1;
-        margin-right: 20px;
-    }
-    .right-card{
-        background: #FFF;
-        border-radius: 4px;
-        padding: 0 20px 20px;
-        width: 600px;
-        box-sizing: border-box;
-        .flow-chart{
-            padding: 0;
-            margin: 0;
-            li{
-                margin: 0;
-                padding: 0 0 20px;
-                list-style: none;
-                display: flex;
-                justify-content: space-between;
-                position: relative;
-                .right-conetnt{
-                    flex: 1;
-                    .name{
-                        font-size: 12px;
-                        color:#333;
-                        margin-bottom: 10px;
-                        span{
-                            color: #999;
-                            float: right;
-                        }
-                    }
-                    .remark{
-                        padding: 10px;
-                        color: #666666;
-                        font-size: 12px;
-                        background: #f1f1f1;
-                        border-radius: 2px;
-                        .label{
-                            color: #39C55A;
-                            margin-bottom: 10px;
-                        }
-                    }
-                }
-                .left-icon{
-                    width: 40px;
-                    height: 40px;
-                    text-align: center;
-                    line-height: 40px;
-                    background: #0084FF;
-                    border-radius: 10px;
-                    color: #fff;
-                    font-size: 20px;
-                    position: relative;
-                    margin-right:27px ;
-                    z-index: 2;
-                    .right-btm-status{
-                        position: absolute;
-                        bottom: 0px;
-                        right: -10px;
-                        height: 20px;
-                        width: 20px;
-                        line-height: 16px;
-                        border-radius: 10px;
-                        background: #39C55A;
-                        border:2px solid #fff;
-                        font-size: 12px;
-                        box-sizing: border-box;
-                    }
-                }
-            }
-            li::before{
-                content: '';
-                position: absolute;
-                top: 0;
-                left: 20px;
-                width: 2px;
-                height: 100%;
-                background: #ddd;
-                z-index: 1;
+  display: flex;
+  justify-content: space-between;
+  margin-top: 20px;
+  padding: 0 20px;
+  .left-card {
+    background: #fff;
+    border-radius: 4px;
+    padding: 20px;
+    flex: 1;
+    margin-right: 20px;
+  }
+  .right-card {
+    background: #fff;
+    border-radius: 4px;
+    padding: 0 20px 20px;
+    width: 600px;
+    box-sizing: border-box;
+    .flow-chart {
+      padding: 0;
+      margin: 0;
+      li {
+        margin: 0;
+        padding: 0 0 20px;
+        list-style: none;
+        display: flex;
+        justify-content: space-between;
+        position: relative;
+        .right-conetnt {
+          flex: 1;
+          .name {
+            font-size: 12px;
+            color: #333;
+            margin-bottom: 10px;
+            span {
+              color: #999;
+              float: right;
             }
-            li:last-child::before{
-                display: none;
+          }
+          .remark {
+            padding: 10px;
+            color: #666666;
+            font-size: 12px;
+            background: #f1f1f1;
+            border-radius: 2px;
+            .label {
+              color: #39c55a;
+              margin-bottom: 10px;
             }
-            
+          }
         }
+        .left-icon {
+          width: 40px;
+          height: 40px;
+          text-align: center;
+          line-height: 40px;
+          background: #0084ff;
+          border-radius: 10px;
+          color: #fff;
+          font-size: 20px;
+          position: relative;
+          margin-right: 27px;
+          z-index: 2;
+          .right-btm-status {
+            position: absolute;
+            bottom: 0px;
+            right: -10px;
+            height: 20px;
+            width: 20px;
+            line-height: 16px;
+            border-radius: 10px;
+            background: #39c55a;
+            border: 2px solid #fff;
+            font-size: 12px;
+            box-sizing: border-box;
+          }
+        }
+      }
+      li::before {
+        content: "";
+        position: absolute;
+        top: 0;
+        left: 20px;
+        width: 2px;
+        height: 100%;
+        background: #ddd;
+        z-index: 1;
+      }
+      li:last-child::before {
+        display: none;
+      }
     }
+  }
 }
 </style>
 <script setup>
-import { ref, reactive, computed, watch, onMounted, onUnmounted, nextTick, defineEmits, defineExpose } from 'vue'
-const activeName = ref('first')
+import {
+  ref,
+  reactive,
+  computed,
+  watch,
+  onMounted,
+  onUnmounted,
+  nextTick,
+  defineEmits,
+  defineExpose,
+} from "vue";
+const activeName = ref("first");
 const handleClick = (tab, event) => {
-    console.log(tab, event);
-}
+  console.log(tab, event);
+};
 </script>
     

+ 13 - 10
src/views/product/material/index.vue

@@ -402,18 +402,20 @@ const getList = async (req) => {
 
       const productIdList = message.rows.map((x) => x.id);
       // 请求文件数据并回显
-      proxy
-        .post("/fileInfo/getList", { businessIdList: productIdList })
-        .then((fileObj) => {
-          for (let i = 0; i < sourceList.value.data.length; i++) {
-            const e = sourceList.value.data[i];
-            for (const key in fileObj) {
-              if (e.id === key) {
-                e.fileList = fileObj[key];
+      if (productIdList.length > 0) {
+        proxy
+          .post("/fileInfo/getList", { businessIdList: productIdList })
+          .then((fileObj) => {
+            for (let i = 0; i < sourceList.value.data.length; i++) {
+              const e = sourceList.value.data[i];
+              for (const key in fileObj) {
+                if (e.id === key) {
+                  e.fileList = fileObj[key];
+                }
               }
             }
-          }
-        });
+          });
+      }
     });
 };
 const uploadData = ref({});
@@ -432,6 +434,7 @@ const openModal = () => {
   formData.data = {
     definition: "2",
     fileList: [],
+    type: "1",
   };
   fileList.value = [];
   fileListCopy.value = [];

+ 12 - 10
src/views/product/product/index.vue

@@ -381,18 +381,20 @@ const getList = async (req) => {
 
       const productIdList = message.rows.map((x) => x.id);
       // 请求文件数据并回显
-      proxy
-        .post("/fileInfo/getList", { businessIdList: productIdList })
-        .then((fileObj) => {
-          for (let i = 0; i < sourceList.value.data.length; i++) {
-            const e = sourceList.value.data[i];
-            for (const key in fileObj) {
-              if (e.id === key) {
-                e.fileList = fileObj[key];
+      if (productIdList.length > 0) {
+        proxy
+          .post("/fileInfo/getList", { businessIdList: productIdList })
+          .then((fileObj) => {
+            for (let i = 0; i < sourceList.value.data.length; i++) {
+              const e = sourceList.value.data[i];
+              for (const key in fileObj) {
+                if (e.id === key) {
+                  e.fileList = fileObj[key];
+                }
               }
             }
-          }
-        });
+          });
+      }
     });
 };
 

+ 473 - 0
src/views/purchaseManage/purchaseManage/subscribe/index.vue

@@ -0,0 +1,473 @@
+<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事件都能传
+          select: select,
+        }"
+        :action-list="[
+          {
+            text: '发起申购',
+            action: () => openModal('add'),
+          },
+        ]"
+        @get-list="getList"
+      >
+        <template #fileSlot="{ item }">
+          <div
+            style="cursor: pointer; color: #409eff"
+            @click="handleClickFile(item)"
+          >
+            {{ item.fileName }}
+          </div>
+        </template>
+      </byTable>
+    </div>
+    <el-dialog
+      :title="modalType == 'add' ? '添加供应商' : '编辑供应商'"
+      v-model="dialogVisible"
+      width="800"
+      v-loading="loading"
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="byform"
+      >
+        <template #address>
+          <el-row :gutter="10" style="width: 100%">
+            <el-col :span="8">
+              <el-select v-model="formData.data.aa" placeholder="国家">
+                <el-option v-for="item in 3" label="ceshi" value="1">
+                </el-option>
+              </el-select>
+            </el-col>
+            <el-col :span="8">
+              <el-select v-model="formData.data.aa" placeholder="省/洲">
+                <el-option v-for="item in 3" label="ceshi" value="1">
+                </el-option>
+              </el-select>
+            </el-col>
+            <el-col :span="8">
+              <el-select v-model="formData.data.aa" placeholder="城市">
+                <el-option v-for="item in 3" label="ceshi" value="1">
+                </el-option>
+              </el-select>
+            </el-col>
+          </el-row>
+          <el-row style="margin-top: 20px; width: 100%">
+            <el-col :span="24">
+              <el-input v-model="formData.data.bb" type="textarea"> </el-input>
+            </el-col>
+          </el-row>
+        </template>
+
+        <template #contact>
+          <el-row :gutter="10" style="width: 100%">
+            <el-col :span="8">
+              <el-input v-model="formData.data.aa" placeholder="联系人">
+              </el-input>
+            </el-col>
+            <el-col :span="16">
+              <el-input v-model="formData.data.aa" placeholder="联系电话">
+              </el-input>
+            </el-col>
+          </el-row>
+        </template>
+
+        <template #fileSlot>
+          <div>
+            <el-upload
+              v-model:fileList="fileList"
+              class="upload-demo"
+              action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+              :limit="3"
+              :data="uploadData"
+              :on-preview="handlePreview"
+              :on-remove="handleRemove"
+              :on-success="handleSuccess"
+              :before-upload="handleBeforeUpload"
+              accept=".pdf"
+            >
+              <el-button type="primary">选择</el-button>
+              <template #file>
+                <div>
+                  <div style="margin-top: 15px">
+                    <el-tag
+                      class="ml-2"
+                      type="info"
+                      v-for="(item, index) in fileList"
+                      :key="index"
+                      closable
+                      @close="handleClose(index)"
+                      >{{ item.fileName }}</el-tag
+                    >
+                  </div>
+                </div>
+              </template>
+            </el-upload>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm('byform')"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+  
+<script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import FileUpload from "@/components/FileUpload/index";
+import { computed, defineComponent, ref } from "vue";
+import { getToken } from "@/utils/auth";
+
+const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
+const headers = ref({ Authorization: "Bearer " + getToken() });
+const uploadData = ref({});
+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 fileList = ref([]);
+let rules = ref({
+  name: [{ required: true, message: "请输入供应商名称", trigger: "blur" }],
+});
+const { proxy } = getCurrentInstance();
+const selectConfig = reactive([
+  {
+    label: "货品类型",
+    prop: "type",
+    data: [
+      {
+        label: "产品",
+        value: "1",
+      },
+      {
+        label: "物料",
+        value: "2",
+      },
+    ],
+  },
+  {
+    label: "状态",
+    prop: "type",
+    data: [
+      {
+        label: "产品",
+        value: "1",
+      },
+      {
+        label: "物料",
+        value: "2",
+      },
+    ],
+  },
+]);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "申购单号",
+        prop: "name",
+      },
+    },
+    {
+      attrs: {
+        label: "货品类型",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "所属分类",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "货品编码",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "货品名称",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "单位",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "申购数量",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "状态",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "申购原因",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: "200",
+        align: "right",
+      },
+      // 渲染 el-button,一般用在最后一列。
+      renderHTML(row) {
+        return [
+          // {
+          //   attrs: {
+          //     label: "修改",
+          //     type: "primary",
+          //     text: true,
+          //   },
+          //   el: "button",
+          //   click() {
+          //     getDtl(row);
+          //   },
+          // },
+          {
+            attrs: {
+              label: "删除",
+              type: "danger",
+              text: true,
+            },
+            el: "button",
+            click() {
+              // 弹窗提示是否删除
+              ElMessageBox.confirm(
+                "此操作将永久删除该数据, 是否继续?",
+                "提示",
+                {
+                  confirmButtonText: "确定",
+                  cancelButtonText: "取消",
+                  type: "warning",
+                }
+              ).then(() => {
+                // 删除
+                proxy
+                  .post("/productionProcesses/delete", {
+                    id: row.id,
+                  })
+                  .then((res) => {
+                    ElMessage({
+                      message: "删除成功",
+                      type: "success",
+                    });
+                    getList();
+                  });
+              });
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+
+let formData = reactive({
+  data: {
+    type: "1",
+  },
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const byform = 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("/productionProcesses/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 openModal = () => {
+//  proxy.$router.push({
+
+//  })
+// };
+
+const submitForm = () => {
+  if (fileList.value.length > 0) {
+    byform.value.handleSubmit((valid) => {
+      formData.data.fileList = fileList.value;
+      submitLoading.value = true;
+      proxy.post("/productionProcesses/" + modalType.value, formData.data).then(
+        (res) => {
+          ElMessage({
+            message: modalType.value == "add" ? "添加成功" : "编辑成功",
+            type: "success",
+          });
+          fileList.value = [];
+          dialogVisible.value = false;
+          submitLoading.value = false;
+          getList();
+        },
+        (err) => {
+          console.log(err, "aswwwww");
+          submitLoading.value = false;
+        }
+      );
+    });
+  } else {
+    return ElMessage({
+      message: "请上传附件!",
+      type: "info",
+    });
+  }
+};
+
+const getDtl = (row) => {
+  modalType.value = "edit";
+  proxy.post("/productionProcesses/detail", { id: row.id }).then((res) => {
+    fileList.value = [
+      {
+        id: "",
+        fileName: res.fileName,
+        path: "",
+      },
+    ];
+    formData.data = res;
+    dialogVisible.value = true;
+  });
+};
+const handleBeforeUpload = async (file) => {
+  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
+  uploadData.value = res.uploadBody;
+  fileList.value = [
+    {
+      id: res.id,
+      fileName: res.fileName,
+      path: res.fileUrl,
+    },
+  ];
+};
+const handleClickFile = (row) => {
+  ElMessage({
+    message: "数据请求中,请稍后!",
+    type: "success",
+  });
+  let id = row.id;
+  proxy.post("/fileInfo/getList", { businessIdList: [id] }).then((res) => {
+    const file = res[id][0];
+    window.open(file.fileUrl, "_blank");
+  });
+};
+
+const handlePreview = (file) => {
+  console.log(file);
+};
+const handleSuccess = (file) => {
+  console.log(file);
+};
+const handleRemove = (file) => {
+  fileList.value = [];
+};
+const handleClose = (index) => {
+  fileList.value.splice(index, 1);
+};
+getList();
+</script>
+  
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+</style>

+ 441 - 0
src/views/purchaseManage/supplier/supplier/index.vue

@@ -0,0 +1,441 @@
+<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事件都能传
+          select: select,
+        }"
+        :action-list="[
+          {
+            text: '添加供应商',
+            action: () => openModal('add'),
+          },
+        ]"
+        @get-list="getList"
+      >
+        <template #fileSlot="{ item }">
+          <div
+            style="cursor: pointer; color: #409eff"
+            @click="handleClickFile(item)"
+          >
+            {{ item.fileName }}
+          </div>
+        </template>
+      </byTable>
+    </div>
+    <el-dialog
+      :title="modalType == 'add' ? '添加供应商' : '编辑供应商'"
+      v-model="dialogVisible"
+      width="800"
+      v-loading="loading"
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="byform"
+      >
+        <template #address>
+          <el-row :gutter="10" style="width: 100%">
+            <el-col :span="8">
+              <el-select v-model="formData.data.aa" placeholder="国家">
+                <el-option v-for="item in 3" label="ceshi" value="1">
+                </el-option>
+              </el-select>
+            </el-col>
+            <el-col :span="8">
+              <el-select v-model="formData.data.aa" placeholder="省/洲">
+                <el-option v-for="item in 3" label="ceshi" value="1">
+                </el-option>
+              </el-select>
+            </el-col>
+            <el-col :span="8">
+              <el-select v-model="formData.data.aa" placeholder="城市">
+                <el-option v-for="item in 3" label="ceshi" value="1">
+                </el-option>
+              </el-select>
+            </el-col>
+          </el-row>
+          <el-row style="margin-top: 20px; width: 100%">
+            <el-col :span="24">
+              <el-input v-model="formData.data.bb" type="textarea"> </el-input>
+            </el-col>
+          </el-row>
+        </template>
+
+        <template #contact>
+          <el-row :gutter="10" style="width: 100%">
+            <el-col :span="8">
+              <el-input v-model="formData.data.aa" placeholder="联系人">
+              </el-input>
+            </el-col>
+            <el-col :span="16">
+              <el-input v-model="formData.data.aa" placeholder="联系电话">
+              </el-input>
+            </el-col>
+          </el-row>
+        </template>
+
+        <template #fileSlot>
+          <div>
+            <el-upload
+              v-model:fileList="fileList"
+              class="upload-demo"
+              action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+              :limit="3"
+              :data="uploadData"
+              :on-preview="handlePreview"
+              :on-remove="handleRemove"
+              :on-success="handleSuccess"
+              :before-upload="handleBeforeUpload"
+              accept=".pdf"
+            >
+              <el-button type="primary">选择</el-button>
+              <template #file>
+                <div>
+                  <div style="margin-top: 15px">
+                    <el-tag
+                      class="ml-2"
+                      type="info"
+                      v-for="(item, index) in fileList"
+                      :key="index"
+                      closable
+                      @close="handleClose(index)"
+                      >{{ item.fileName }}</el-tag
+                    >
+                  </div>
+                </div>
+              </template>
+            </el-upload>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm('byform')"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+  
+<script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import FileUpload from "@/components/FileUpload/index";
+import { computed, defineComponent, ref } from "vue";
+import { getToken } from "@/utils/auth";
+
+const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
+const headers = ref({ Authorization: "Bearer " + getToken() });
+const uploadData = ref({});
+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 fileList = ref([]);
+let rules = ref({
+  name: [{ required: true, message: "请输入供应商名称", trigger: "blur" }],
+});
+const { proxy } = getCurrentInstance();
+const selectConfig = reactive([
+  {
+    label: "供应商类型",
+    prop: "type",
+    data: [
+      {
+        label: "普通车间",
+        value: "1",
+      },
+      {
+        label: "半自动化车间",
+        value: "2",
+      },
+    ],
+  },
+]);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "供应商类型",
+        prop: "name",
+      },
+    },
+    {
+      attrs: {
+        label: "供应商编码",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "供应商名称",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "所在城市",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "联系人",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "联系人电话",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: "200",
+        align: "right",
+      },
+      // 渲染 el-button,一般用在最后一列。
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "修改",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              getDtl(row);
+            },
+          },
+          {
+            attrs: {
+              label: "删除",
+              type: "danger",
+              text: true,
+            },
+            el: "button",
+            click() {
+              // 弹窗提示是否删除
+              ElMessageBox.confirm(
+                "此操作将永久删除该数据, 是否继续?",
+                "提示",
+                {
+                  confirmButtonText: "确定",
+                  cancelButtonText: "取消",
+                  type: "warning",
+                }
+              ).then(() => {
+                // 删除
+                proxy
+                  .post("/productionProcesses/delete", {
+                    id: row.id,
+                  })
+                  .then((res) => {
+                    ElMessage({
+                      message: "删除成功",
+                      type: "success",
+                    });
+                    getList();
+                  });
+              });
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+
+let formData = reactive({
+  data: {
+    type: "1",
+  },
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const byform = 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("/productionProcesses/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 openModal = () => {
+  dialogVisible.value = true;
+  modalType.value = "add";
+  formData.data = {};
+};
+
+const submitForm = () => {
+  if (fileList.value.length > 0) {
+    byform.value.handleSubmit((valid) => {
+      formData.data.fileList = fileList.value;
+      submitLoading.value = true;
+      proxy.post("/productionProcesses/" + modalType.value, formData.data).then(
+        (res) => {
+          ElMessage({
+            message: modalType.value == "add" ? "添加成功" : "编辑成功",
+            type: "success",
+          });
+          fileList.value = [];
+          dialogVisible.value = false;
+          submitLoading.value = false;
+          getList();
+        },
+        (err) => {
+          console.log(err, "aswwwww");
+          submitLoading.value = false;
+        }
+      );
+    });
+  } else {
+    return ElMessage({
+      message: "请上传附件!",
+      type: "info",
+    });
+  }
+};
+
+const getDtl = (row) => {
+  modalType.value = "edit";
+  proxy.post("/productionProcesses/detail", { id: row.id }).then((res) => {
+    fileList.value = [
+      {
+        id: "",
+        fileName: res.fileName,
+        path: "",
+      },
+    ];
+    formData.data = res;
+    dialogVisible.value = true;
+  });
+};
+const handleBeforeUpload = async (file) => {
+  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
+  uploadData.value = res.uploadBody;
+  fileList.value = [
+    {
+      id: res.id,
+      fileName: res.fileName,
+      path: res.fileUrl,
+    },
+  ];
+};
+const handleClickFile = (row) => {
+  ElMessage({
+    message: "数据请求中,请稍后!",
+    type: "success",
+  });
+  let id = row.id;
+  proxy.post("/fileInfo/getList", { businessIdList: [id] }).then((res) => {
+    const file = res[id][0];
+    window.open(file.fileUrl, "_blank");
+  });
+};
+
+const handlePreview = (file) => {
+  console.log(file);
+};
+const handleSuccess = (file) => {
+  console.log(file);
+};
+const handleRemove = (file) => {
+  fileList.value = [];
+};
+const handleClose = (index) => {
+  fileList.value.splice(index, 1);
+};
+getList();
+</script>
+  
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+</style>

+ 405 - 0
src/views/purchaseManage/supplier/supplyPrice/index.vue

@@ -0,0 +1,405 @@
+<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事件都能传
+          select: select,
+        }"
+        :action-list="[
+          {
+            text: '添加供应价格',
+            action: () => openModal('add'),
+          },
+        ]"
+        @get-list="getList"
+      >
+        <template #fileSlot="{ item }">
+          <div
+            style="cursor: pointer; color: #409eff"
+            @click="handleClickFile(item)"
+          >
+            {{ item.fileName }}
+          </div>
+        </template>
+      </byTable>
+    </div>
+    <el-dialog
+      :title="modalType == 'add' ? '添加供应价格' : '编辑供应价格'"
+      v-model="dialogVisible"
+      width="800"
+      v-loading="loading"
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="byform"
+      >
+        <template #details>
+          <div>
+            <el-button type="primary" @click="openProduct = true">
+              添加货品
+            </el-button>
+
+            <el-form
+              ref="tableForm"
+              :model="formData.data"
+              :rules="rules"
+              label-width="0px"
+              style="margin-top: 15px"
+            >
+              <el-table :data="formData.data.goodsList">
+                <el-table-column prop="productCode" label="货品编码" />
+                <el-table-column prop="productName" label="货品名称" />
+                <el-table-column prop="productName" label="规格型号" />
+                <el-table-column prop="productUnit" label="单位" />
+                <el-table-column prop="quantity" label="供应单价" width="150">
+                  <template #default="{ row, $index }">
+                    <el-form-item
+                      :prop="'goodsList.' + $index + '.quantity'"
+                      :rules="rules.quantity"
+                      :inline-message="true"
+                    >
+                      <el-input-number
+                        v-model="row.quantity"
+                        :precision="2"
+                        :controls="false"
+                        :min="1"
+                      />
+                    </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>
+            </el-form>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm('byform')"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      v-model="openProduct"
+      title="选择货品"
+      width="70%"
+      append-to-body
+    >
+      <SelectGoods
+        @cancel="openProduct = false"
+        @pushGoods="pushGoods"
+      ></SelectGoods>
+    </el-dialog>
+  </div>
+</template>
+  
+<script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import FileUpload from "@/components/FileUpload/index";
+import { computed, defineComponent, ref } from "vue";
+import { getToken } from "@/utils/auth";
+import SelectGoods from "@/components/product/SelectGoods";
+
+const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
+const headers = ref({ Authorization: "Bearer " + getToken() });
+const uploadData = ref({});
+const loading = ref(false);
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+  },
+});
+let dialogVisible = ref(false);
+let openProduct = ref(false);
+
+let modalType = ref("add");
+let fileList = ref([]);
+let rules = ref({
+  name: [{ required: true, message: "请输入供应价格名称", trigger: "blur" }],
+});
+const { proxy } = getCurrentInstance();
+const selectConfig = reactive([
+  {
+    label: "供应价格类型",
+    prop: "type",
+    data: [
+      {
+        label: "普通车间",
+        value: "1",
+      },
+      {
+        label: "半自动化车间",
+        value: "2",
+      },
+    ],
+  },
+]);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "供应价格类型",
+        prop: "name",
+      },
+    },
+    {
+      attrs: {
+        label: "供应价格编码",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "供应价格名称",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "所在城市",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "联系人",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "联系人电话",
+        prop: "remarks",
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: "200",
+        align: "right",
+      },
+      // 渲染 el-button,一般用在最后一列。
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "修改",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              getDtl(row);
+            },
+          },
+          {
+            attrs: {
+              label: "删除",
+              type: "danger",
+              text: true,
+            },
+            el: "button",
+            click() {
+              // 弹窗提示是否删除
+              ElMessageBox.confirm(
+                "此操作将永久删除该数据, 是否继续?",
+                "提示",
+                {
+                  confirmButtonText: "确定",
+                  cancelButtonText: "取消",
+                  type: "warning",
+                }
+              ).then(() => {
+                // 删除
+                proxy
+                  .post("/productionProcesses/delete", {
+                    id: row.id,
+                  })
+                  .then((res) => {
+                    ElMessage({
+                      message: "删除成功",
+                      type: "success",
+                    });
+                    getList();
+                  });
+              });
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+
+let formData = reactive({
+  data: {
+    goodsList: [],
+  },
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const byform = ref(null);
+const formConfig = computed(() => {
+  return [
+    // {
+    //   type: "radio",
+    //   prop: "name",
+    //   label: "供应价格类型",
+    //   required: true,
+    //   border: true,
+    //   data: [
+    //     { label: "贸易商", value: "1" },
+    //     { label: "工厂", value: "2" },
+    //   ],
+    // },
+    {
+      type: "select",
+      prop: "name",
+      label: "供应商",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "details",
+      label: "供应明细",
+      required: true,
+    },
+  ];
+});
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/productionProcesses/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 openModal = () => {
+  dialogVisible.value = true;
+  modalType.value = "add";
+  formData.data = {
+    goodsList: [],
+  };
+};
+
+const submitForm = () => {
+  if (formData.data.goodsList.length > 0) {
+    byform.value.handleSubmit((valid) => {
+      submitLoading.value = true;
+      proxy.post("/productionProcesses/" + modalType.value, formData.data).then(
+        (res) => {
+          ElMessage({
+            message: modalType.value == "add" ? "添加成功" : "编辑成功",
+            type: "success",
+          });
+          fileList.value = [];
+          dialogVisible.value = false;
+          submitLoading.value = false;
+          getList();
+        },
+        (err) => {
+          console.log(err, "aswwwww");
+          submitLoading.value = false;
+        }
+      );
+    });
+  } else {
+    return ElMessage({
+      message: "请添加供应明细!",
+      type: "info",
+    });
+  }
+};
+
+const getDtl = (row) => {
+  modalType.value = "edit";
+  proxy.post("/productionProcesses/detail", { id: row.id }).then((res) => {
+    fileList.value = [
+      {
+        id: "",
+        fileName: res.fileName,
+        path: "",
+      },
+    ];
+    formData.data = res;
+    dialogVisible.value = true;
+  });
+};
+
+// const handleClickFile = (row) => {
+//   ElMessage({
+//     message: "数据请求中,请稍后!",
+//     type: "success",
+//   });
+//   let id = row.id;
+//   proxy.post("/fileInfo/getList", { businessIdList: [id] }).then((res) => {
+//     const file = res[id][0];
+//     window.open(file.fileUrl, "_blank");
+//   });
+// };
+
+const handleRemove = (index) => {
+  formData.data.goodsList.splice(index, 1);
+  return ElMessage({
+    message: "删除成功!",
+    type: "success",
+  });
+};
+
+const pushGoods = (goods) => {
+  formData.data.goodsList = formData.data.goodsList.concat(goods);
+  return ElMessage({
+    message: "添加成功!",
+    type: "success",
+  });
+};
+getList();
+</script>
+  
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+</style>