Browse Source

外协发出单

ezhizao 1 year ago
parent
commit
424ecbf4a9

+ 46 - 0
src/api/business/outsourcedOrder.js

@@ -0,0 +1,46 @@
+import request from '@/utils/request'
+
+const baseUrl = import.meta.env.VITE_APP_PRODUCTION_API
+
+// 查询外协单
+export function listOrder(query) {
+	return request({
+		url: baseUrl + '/business/outsource/list',
+		method: 'get',
+		params: query
+	})
+}
+
+// 查询外协单
+export function getOrder(id) {
+	return request({
+		url: baseUrl + '/business/outsource/' + id,
+		method: 'get'
+	})
+}
+
+// 新增外协单
+export function addOrder(data) {
+	return request({
+		url: baseUrl + '/business/outsource',
+		method: 'post',
+		data: data
+	})
+}
+
+// 修改外协单
+export function updateOrder(data) {
+	return request({
+		url: baseUrl + '/business/outsource',
+		method: 'put',
+		data: data
+	})
+}
+
+// 删除外协单
+export function delOrder(id) {
+	return request({
+		url: baseUrl + '/business/outsource/' + id,
+		method: 'delete'
+	})
+}

+ 44 - 0
src/api/business/outsourcedOrderDetail.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询外协单从列表
+export function listDetail(query) {
+  return request({
+    url: '/business/detail/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询外协单从详细
+export function getDetail(id) {
+  return request({
+    url: '/business/detail/' + id,
+    method: 'get'
+  })
+}
+
+// 新增外协单从
+export function addDetail(data) {
+  return request({
+    url: '/business/detail',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改外协单从
+export function updateDetail(data) {
+  return request({
+    url: '/business/detail',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除外协单从
+export function delDetail(id) {
+  return request({
+    url: '/business/detail/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
src/api/business/outsourcedOrderDetailProcess.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询外协单从对应的外协工序的从列表
+export function listProcess(query) {
+  return request({
+    url: '/business/process/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询外协单从对应的外协工序的从详细
+export function getProcess(id) {
+  return request({
+    url: '/business/process/' + id,
+    method: 'get'
+  })
+}
+
+// 新增外协单从对应的外协工序的从
+export function addProcess(data) {
+  return request({
+    url: '/business/process',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改外协单从对应的外协工序的从
+export function updateProcess(data) {
+  return request({
+    url: '/business/process',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除外协单从对应的外协工序的从
+export function delProcess(id) {
+  return request({
+    url: '/business/process/' + id,
+    method: 'delete'
+  })
+}

+ 8 - 0
src/api/business/product.js

@@ -53,3 +53,11 @@ export function getProductsForSupplier(query) {
 		params: query
 	})
 }
+
+export function getProductsForOutsource(query) {
+	return request({
+		url: baseUrl + '/business/product/getProductsForOutsource',
+		method: 'get',
+		params: query
+	})
+}

+ 78 - 181
src/assets/styles/ezhizao/form.css

@@ -1,238 +1,135 @@
 .form-container {
-  position: relative;
-  flex-direction: column;
-  width: 100%;
+	position: relative;
+	flex-direction: column;
+	width: 100%;
 }
 .form-container.is-fullscreen {
-  position: fixed !important;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  z-index: 10001;
-  background-color: #fff;
+	position: fixed !important;
+	top: 0;
+	right: 0;
+	bottom: 0;
+	left: 0;
+	z-index: 10001;
+	background-color: #fff;
 }
 .form-container .el-input,
 .form-container .el-input-number,
 .form-container .el-select {
-  width: 100%;
+	width: 100%;
 }
 .form-container .el-input-number .el-input__inner {
-  text-align: right;
+	text-align: right;
 }
 .form-container .form-title-container {
-  height: 30px;
-  padding: 5px;
-  background-color: #527098;
+	height: 30px;
+	padding: 5px;
+	background-color: #527098;
 }
-.form-container .form-title-container .title-label{
-  font-size: 14px;
-  font-weight: bold;
-  color: #f1f1f1;
+.form-container .form-title-container .title-label {
+	font-size: 14px;
+	font-weight: bold;
+	color: #f1f1f1;
 }
-.form-container .form-title-container > i{
-  float: right;
-  font-size: 18px;
-  color: #F69600;
-  cursor: pointer;
+.form-container .form-title-container > i {
+	float: right;
+	font-size: 18px;
+	color: #f69600;
+	cursor: pointer;
 }
-.form-container .form-title-container i:hover{
-  color: rgb(252, 203, 124);
+.form-container .form-title-container i:hover {
+	color: rgb(252, 203, 124);
 }
 /**************************************** for-btns-container ****************************************/
-.form-container .form-btns-container{
-  position: relative;
-  height: 40px;
-  top: 0;
-  right:0;
-  left: 0;
-  padding-top: 4px;
-  padding-left: 4px;
-  background-color: #E3E9F0;
-  box-sizing: border-box;
-  border-bottom: 1px solid #D6DEE9;
+.form-container .form-btns-container {
+	display: flex;
+	position: relative;
+	height: 40px;
+	top: 0;
+	right: 0;
+	left: 0;
+	padding-left: 8px;
+	background-color: #e3e9f0;
+	box-sizing: border-box;
+	border-bottom: 1px solid #d6dee9;
+	align-items: center;
 }
 .form-container .form-btns-container > .title-label {
-  font-size: 16px;
-  margin-right: 16px;
+	display: flex;
+	align-items: center;
 }
-.form-container .form-btns-container > .el-button+.el-button {
-  margin-left: 2px;
+.form-container .form-btns-container > .title-label > span {
+	display: inline-block;
+	font-size: 16px;
+	margin: 0 16px 0 8px;
+}
+.form-container .form-btns-container > .el-button + .el-button {
+	margin-left: 2px;
 }
-
 
 .form-container .form-btns-container > .screen-btn,
 .form-container .form-btns-container > .close-btn {
-  position: absolute;
-  font-size: 12px;
-  top: 0px;
-  right: 40px;
-  cursor: pointer;
-  width: 40px;
-  height: 31px;
-  text-align: center;
-  line-height: 30px;
-  /* border: 1px solid #527098; */
+	position: absolute;
+	font-size: 12px;
+	top: 0px;
+	right: 40px;
+	cursor: pointer;
+	width: 40px;
+	height: 31px;
+	text-align: center;
+	line-height: 30px;
+	/* border: 1px solid #527098; */
 }
 .form-container .form-btns-container > .close-btn {
-  right: 0px;
-  font-size: 16px;
-  /* border: 1px solid #527098; */
+	right: 0px;
+	font-size: 16px;
+	/* border: 1px solid #527098; */
 }
 .form-container .form-btns-container > .screen-btn:hover {
-  background-color: #9cb2cf;
+	background-color: #9cb2cf;
 }
 .form-container .form-btns-container > .close-btn:hover {
-  background-color: #F56C6C;
-  color: #fff;
+	background-color: #f56c6c;
+	color: #fff;
 }
 
 .form-container .form-btns-container > .screen-btn > span,
 .form-container .form-btns-container > .close-btn > span {
-  margin-left: 4px;
+	margin-left: 4px;
 }
 
 /****************************************************************************************************/
 
 .form-container .master-container {
-  padding: 16px 16px 0 16px;
+	padding: 16px 16px 0 16px;
 }
 .form-container .master-container .el-input--mini {
-  line-height: normal;
+	line-height: normal;
 }
 .form-container .master-container .el-form-item--mini.el-form-item {
-  margin-bottom: 16px;
-}
-.form-container .details-container {
-  display: flex;
-  flex-direction: column;
-  position: relative;
-  flex-grow: 1;
-  overflow: hidden;
-}
-.form-container .details-container > .el-row {
-  position: relative;
-  height: 100%;
-}
-.form-container .details-container > .el-row > .el-col {
-  position: relative;
-  display: flex;
-  height: 100%;
-  flex-direction: column;
-}
-.form-container .details-container .details-head {
-  padding: 2px 8px;
-  height: 28px;
-  background-color: #E3E9F0;
-  box-sizing: border-box;
-}
-.form-container .details-container .details-head > div {
-  float: left;
-  box-sizing: border-box;
-}
-.form-container .details-container .details-head > div.title {
-  padding-top: 4px;
-  font-size: 12px;
-  margin-right: 16px;
-}
-.form-container .details-container .list-header-row > th,
-.form-container .details-container .el-table thead.is-group .list-header-row th{
-  background: #F1F4F8 !important;
-  border-color: #D6DEE9 !important;
-  padding: 4px 0 !important;
-}
-.form-container .details-container .details-body {
-  position: relative;
-  flex-grow: 1;
-}
-.form-container .details-container .details-body > div {
-  position: absolute;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-}
-.form-container .details-container .details-body .el-table{
-  border: 1px solid #D6DEE9;
-}
-
-.form-container .details-container .details-body .el-table th.is-group,
-.form-container .details-container .details-body .el-table th.is-center,
-.form-container .details-container .details-body .el-table th.is-leaf{
-  padding: 4px 0;
-  border-color: #D6DEE9;
-  color: #333;
-}
-.form-container .details-container .details-body .el-table th > .cell {
-  padding-right: 8px;
-  padding-left: 8px;
-}
-.form-container .details-container .details-body .el-table td {
-  padding: 0;
-}
-.form-container .details-container .details-body .el-table td > .cell {
-  padding-right: 1px;
-  padding-left: 1px;
-  height: 30px;
-}
-.form-container .details-container .details-body .el-table td > .cell > div {
-  position: relative;
-  padding-top: 1px;
-  line-height: 29px;
-  box-sizing: border-box;
-}
-.form-container .details-container .details-body .el-table td > .cell > div > .required {
-  position: absolute;
-  color: #a00;
-  top: 2px;
-  right: 2px;
-  line-height: 14px;
-}
-.form-container .details-container .details-body .el-table td > .cell > div .el-input--mini {
-  line-height: 27px;
-}
-.form-container .details-container .details-body .el-table td > .cell > div > .el-input > .el-input__inner {
-  padding: 0 2px;
-  box-sizing: border-box;
-}
-.form-container .details-container .details-body .el-table td > .cell > div > .el-input-number .el-input__inner,
-.form-container .details-container .details-body .el-table td > .cell > div > .el-select .el-input__inner {
-  padding-left: 2px;
-  padding-right: 30px;
-}
-.form-container .details-container .details-body .el-table td > .cell > div > .el-select.txtC .el-input__inner {
-  text-align: center;
-}
-
-.form-container .details-container .details-body .el-table td > .cell .el-button--mini.is-circle{
-  padding: 5px;
+	margin-bottom: 16px;
 }
 
 .form-container .dialog-foot {
-  margin: 0 8px;
-  height: 32px;
-  line-height: 32px;
-  font-size: 12px;
+	margin: 0 8px;
+	height: 32px;
+	line-height: 32px;
+	font-size: 12px;
 }
 
-.form-container .dialog-foot > span+span {
-  margin-left: 16px;
+.form-container .dialog-foot > span + span {
+	margin-left: 16px;
 }
 
 /** el-input-number 样式 */
 .form-container .el-input-number .el-input__inner {
-  text-align: left;
+	text-align: left;
 }
 
 .form-container .el-input-number.is-controls-right .el-input__wrapper {
-  padding-right: 42px;
-  padding-left: 8px;
+	padding-right: 42px;
+	padding-left: 8px;
 }
 
-.form-container .addNum {
-  margin-left:2px;margin-right:2px;width: 60px;
+.form-container .form-details-btns-container {
+	margin: 0 8px;
 }
-
-.addUnit{
-  display: inline-block; padding-top: 5px; padding-right: 10px; padding-left: 2px; font-size: 12px;
-}

+ 146 - 0
src/views/business/outsource/DialogProducts.vue

@@ -0,0 +1,146 @@
+<template>
+	<el-dialog title="添加产品" v-model="visible" width="800px" height="400px" @close="close" append-to-body draggable>
+		<el-form ref="dialogForm" :model="queryParams" :inline="true" style="padding-top: 16px">
+			<el-form-item label="产品描述:" prop="description" label-width="104">
+				<el-input
+					v-model.trim="queryParams.description"
+					type="text"
+					@keydown.enter.prevent
+					style="width: 160px"
+					placeholder="请输入关键字"
+					:clearable="true"
+					@keyup.enter="handleSearch"
+				/>
+			</el-form-item>
+			<el-form-item v-if="supplierId !== '' && supplierId !== '0'" label="只看外协商配置的产品:" prop="description">
+				<el-switch
+					v-model="queryParams.isSupplierProducts"
+					active-text="是"
+					:active-value="1"
+					inactive-text="否"
+					:inactive-value="0"
+				/>
+			</el-form-item>
+			<el-form-item label-width="20px">
+				<el-button type="info" icon="Search" @click="handleSearch">搜索</el-button>
+			</el-form-item>
+		</el-form>
+
+		<el-table
+			ref="dialogTable"
+			:data="productList"
+			size="small"
+			v-loading="loading"
+			border
+			height="370px"
+			@selection-change="handleSelectionChange"
+		>
+			<el-table-column type="selection" width="40" align="center" />
+			<el-table-column type="index" label="行号" width="50" align="center" />
+			<el-table-column label="料号" align="center" prop="productCode" width="120" />
+			<el-table-column label="产品描述" align="center" prop="description" />
+		</el-table>
+		<!-- 分页 -->
+		<pagination
+			v-show="total > 0"
+			:total="total"
+			v-model:page="queryParams.pageNum"
+			v-model:limit="queryParams.pageSize"
+			@pagination="getList"
+		/>
+		<template #footer>
+			<div class="dialog-footer">
+				<el-button type="primary" icon="Check" :disabled="selections.length === 0" @click="handleMultipleSelected">
+					确 定
+				</el-button>
+				<el-button type="danger" icon="Close" @click="close">取 消</el-button>
+			</div>
+		</template>
+	</el-dialog>
+</template>
+<script setup>
+import { getProductsForOutsource } from '@/api/business/product'
+const { proxy } = getCurrentInstance()
+/** 字典数组区 */
+const { process_status } = proxy.useDict('process_status')
+/** 工序变量 */
+const total = ref(0)
+const props = defineProps({
+	multipleSelected: {
+		type: Function,
+		default: null
+	},
+	supplierId: {
+		type: String,
+		default: ''
+	}
+})
+
+const { multipleSelected, supplierId } = toRefs(props)
+const productList = ref([])
+const visible = ref(false)
+const loading = ref(false)
+const queryParams = ref({
+	// 是否看所有产品【0:看全部产品,1:只看该外协商配置的产品】
+	isSupplierProducts: 0,
+	supplierId: '',
+	description: '',
+	pageNum: 1,
+	pageSize: 10
+})
+const selections = ref([])
+
+/**
+ * 对话框打开 事件
+ */
+function open() {
+	visible.value = true
+	getList()
+}
+
+/**
+ * 对话框关闭 事件
+ */
+function close() {
+	proxy.$refs.dialogForm.resetFields()
+	proxy.$refs.dialogTable.clearSelection()
+	queryParams.value.pageNum = 1
+	visible.value = false
+}
+
+/**
+ * 加载数据
+ */
+function getList() {
+	loading.value = true
+	queryParams.value.supplierId = props.supplierId
+	getProductsForOutsource(queryParams.value).then((res) => {
+		productList.value = res.rows
+		total.value = res.total
+		loading.value = false
+	})
+}
+
+/**
+ * 列表checkbox列选择 事件
+ */
+function handleSelectionChange(selection) {
+	selections.value = selection
+}
+
+/**  搜索 事件 */
+function handleSearch() {
+	getList()
+}
+/** 多选事件 */
+function handleMultipleSelected() {
+	if (multipleSelected.value) {
+		multipleSelected.value(selections.value)
+	}
+	close()
+}
+
+defineExpose({
+	open
+})
+</script>

+ 132 - 0
src/views/business/outsource/DialogSuppliers.vue

@@ -0,0 +1,132 @@
+<template>
+	<el-dialog title="添加外协商" v-model="visible" width="600px" height="400px" @close="close" append-to-body draggable>
+		<el-form ref="dialogForm" class="master-container" :model="queryParams" :inline="true" style="align-items: center">
+			<div style="display: flex">
+				<el-form-item label="外协商名称:" prop="name">
+					<el-input
+						v-model.trim="queryParams.name"
+						type="text"
+						@keydown.enter.prevent
+						style="width: 120px"
+						placeholder="请输入关键字"
+						:clearable="true"
+						@keyup.enter="handleSearch"
+					/>
+				</el-form-item>
+				<el-form-item label="助记码:" prop="name">
+					<el-input
+						v-model.trim="queryParams.mnemonicCode"
+						type="text"
+						@keydown.enter.prevent
+						style="width: 120px"
+						placeholder="请输入关键字"
+						:clearable="true"
+						@keyup.enter="handleSearch"
+					/>
+				</el-form-item>
+				<el-form-item>
+					<el-button type="info" icon="Search" @click="handleSearch">搜索</el-button>
+				</el-form-item>
+			</div>
+		</el-form>
+
+		<el-table ref="dialogTable" :data="dataList" size="small" v-loading="loading" border height="370px">
+			<el-table-column type="index" label="行号" width="50" align="center" />
+			<el-table-column label="外协商名称" align="center" prop="name" />
+			<el-table-column label="助记码" align="center" prop="mnemonicCode" width="120" />
+			<el-table-column label="操作" width="64" align="center">
+				<template #default="scope">
+					<el-button type="success" icon="finished" circle @click="handleSingleSelected(scope.row)" />
+				</template>
+			</el-table-column>
+		</el-table>
+		<!-- 分页 -->
+		<pagination
+			v-show="total > 0"
+			:total="total"
+			v-model:page="queryParams.pageNum"
+			v-model:limit="queryParams.pageSize"
+			@pagination="getList"
+		/>
+	</el-dialog>
+</template>
+<script setup>
+import { list } from '@/api/business/supplier'
+const { proxy } = getCurrentInstance()
+/** 字典数组区 */
+const { process_status } = proxy.useDict('process_status')
+/** 工序变量 */
+const total = ref(0)
+const props = defineProps({
+	singleSelected: {
+		type: Function,
+		default: null
+	}
+})
+
+const { singleSelected } = toRefs(props)
+const dataList = ref([])
+const visible = ref(false)
+const loading = ref(false)
+const queryParams = ref({
+	name: '',
+	pageNum: 1,
+	pageSize: 10
+})
+const selections = ref([])
+
+/**
+ * 对话框打开 事件
+ */
+function open() {
+	visible.value = true
+	getList()
+}
+
+/**
+ * 对话框关闭 事件
+ */
+function close() {
+	proxy.$refs.dialogForm.resetFields()
+	proxy.$refs.dialogTable.clearSelection()
+	queryParams.value.pageNum = 1
+	visible.value = false
+}
+
+/**
+ * 加载数据
+ */
+function getList() {
+	loading.value = true
+	queryParams.value.supplierId = props.supplierId
+	list(queryParams.value).then((res) => {
+		dataList.value = res.rows
+		total.value = res.total
+		loading.value = false
+	})
+}
+
+/**
+ * 列表checkbox列选择 事件
+ */
+function handleSelectionChange(selection) {
+	selections.value = selection
+}
+
+/**  搜索 事件 */
+function handleSearch() {
+	getList()
+}
+
+/** 单选事件 */
+function handleSingleSelected(row) {
+	if (singleSelected.value) {
+		singleSelected.value(row)
+	}
+	close()
+}
+
+defineExpose({
+	open
+})
+</script>

+ 332 - 0
src/views/business/outsource/form.vue

@@ -0,0 +1,332 @@
+<template>
+	<el-drawer title="外协单信息" :with-header="false" v-model="visible" direction="rtl" size="100%">
+		<div class="form-container column-container">
+			<div class="form-btns-container">
+				<span class="title-label">
+					<el-icon><Document /></el-icon>
+					<span>外协单信息</span>
+				</span>
+				<el-button-group>
+					<el-button v-if="editStatus" type="primary" icon="Finished" @click="submitForm"> 保存 </el-button>
+					<el-button v-else type="warning" size="small" icon="Edit" @click="editStatus = true">编辑</el-button>
+					<el-button v-if="form.id && editStatus" type="info" size="small" icon="Close" @click="editStatus = false">
+						取消编辑
+					</el-button>
+					<el-button v-if="form.id" type="success" size="small" @click="getForm">
+						<i class="fa fa-refresh" aria-hidden="true" /> 刷新
+					</el-button>
+				</el-button-group>
+
+				<div class="close-btn" @click="cancel">
+					<i class="fa fa-times" aria-hidden="true" />
+					<!-- <span>关闭</span> -->
+				</div>
+			</div>
+			<el-form ref="formRef" class="master-container" :model="form" :rules="rules" label-width="120px">
+				<el-row :gutter="20">
+					<el-col :span="6">
+						<el-form-item label="单据号" prop="formCode">
+							<el-input v-if="editStatus" v-model="form.formCode" disabled placeholder="系统自动生成" />
+							<span v-else>{{ form.formCode }}</span>
+						</el-form-item>
+					</el-col>
+					<el-col :span="6">
+						<el-form-item label="表单日期" prop="formDate">
+							<el-date-picker
+								v-if="editStatus"
+								clearable
+								v-model="form.formDate"
+								type="date"
+								value-format="YYYY-MM-DD"
+								placeholder="请选择表单日期"
+								style="width: 100%"
+							>
+							</el-date-picker>
+							<span v-else>{{ parseTime(form.formDate, '{y}-{m}-{d}') }}</span>
+						</el-form-item>
+					</el-col>
+					<el-col :span="6">
+						<el-form-item label="外协商名称" prop="supplierName">
+							<el-input v-if="editStatus" v-model="form.supplierName" readonly placeholder="请输入外协商名称">
+								<template #append>
+									<el-button icon="Search" @click="handleShowDialogSuppliers" />
+								</template>
+							</el-input>
+							<span v-else>{{ form.supplierName }}</span>
+						</el-form-item>
+					</el-col>
+					<el-col :span="6">
+						<el-form-item label="送货方式" prop="deliveryMethod">
+							<el-select v-if="editStatus" v-model="form.deliveryMethod" clearable placeholder="请选择">
+								<el-option v-for="dict in deliveryMethod" :key="dict.value" :label="dict.label" :value="dict.value" />
+							</el-select>
+							<span v-else>{{ form.deliveryMethod }}</span>
+						</el-form-item>
+					</el-col>
+					<el-col :span="6">
+						<el-form-item label="运费单价" prop="freightPrice">
+							<el-input-number
+								v-if="editStatus"
+								v-model="form.freightPrice"
+								:min="0"
+								:precision="2"
+								controls-position="right"
+							/>
+							<span v-else>{{ form.freightPrice }}</span>
+						</el-form-item>
+					</el-col>
+					<el-col :span="6">
+						<el-form-item label="运费总价" prop="freightAmount">
+							<el-input-number
+								v-if="editStatus"
+								v-model="form.freightAmount"
+								:min="0"
+								:precision="2"
+								controls-position="right"
+							/>
+							<span v-else>{{ form.freightAmount }}</span>
+						</el-form-item>
+					</el-col>
+					<el-col :span="6">
+						<el-form-item label="带箱方式:" prop="packagingMethod">
+							<el-select v-if="editStatus" v-model="form.packagingMethod" clearable placeholder="请选择">
+								<el-option v-for="dict in packagingMethod" :key="dict.value" :label="dict.label" :value="dict.value" />
+							</el-select>
+							<span v-else>{{ form.packagingMethod }}</span>
+						</el-form-item>
+					</el-col>
+					<el-col :span="6">
+						<el-form-item label="备注" prop="remark">
+							<el-input v-if="editStatus" v-model="form.remark" placeholder="请输入备注" />
+							<span v-else>{{ form.remark }}</span>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<!-- 渲染数据区 -->
+			<div class="form-details-btns-container">
+				<el-button type="primary" icon="Plus" @click="handleShowDialogProducts" v-hasPermi="['business:outsource:add']">
+					添加外协产品明细
+				</el-button>
+			</div>
+			<div class="el-table-container">
+				<div class="el-table-inner-container">
+					<el-table v-loading="loading" :data="formatDetails" size="small" border height="100%">
+						<el-table-column label="批次号" align="center" prop="lotCode" width="120" />
+						<el-table-column label="产品描述" align="center" prop="supplierName" width="320" />
+						<el-table-column
+							:label="form.packagingMethod === 0 ? '箱号' : '原箱号'"
+							align="center"
+							prop="original_carrier"
+							width="320"
+						/>
+						<el-table-column
+							v-if="form.packagingMethod === 1"
+							label="新箱号"
+							align="center"
+							prop="new_carrier"
+							width="320"
+						>
+							<template #default="scope">
+								<el-input v-if="editStatus" v-model="scope.row.originalCarrier" readonly placeholder="请选择新箱号">
+									<template #append>
+										<el-button icon="Search" @click="handleShowDialogOutsourceCarriers" />
+									</template>
+								</el-input>
+								<span v-else>{{ scope.row.originalCarrier }}</span>
+							</template>
+						</el-table-column>
+						<el-table-column label="备注" align="center" prop="remark" />
+						<el-table-column
+							v-if="editStatus"
+							label="操作"
+							align="center"
+							class-name="small-padding fixed-width"
+							width="144"
+						>
+							<template #default="scope">
+								<el-button
+									link
+									type="danger"
+									icon="Delete"
+									@click="handleDelete(scope.row)"
+									v-hasPermi="['business:outsource:remove']"
+								>
+									删除
+								</el-button>
+							</template>
+						</el-table-column>
+					</el-table>
+				</div>
+			</div>
+		</div>
+		<!-- 外协商选择 -->
+		<dialog-suppliers ref="dialogSuppliersRef" :single-selected="handleSingleSelectedSupplier" />
+		<!-- 产品选择 -->
+		<dialog-products
+			ref="dialogProductsRef"
+			:supplier-id="form.supplierId"
+			:multiple-selected="handleMultipleSelectedProducts"
+		/>
+	</el-drawer>
+</template>
+<script setup>
+import { getOrder, addOrder, updateOrder } from '@/api/business/outsourcedOrder'
+import dialogSuppliers from './DialogSuppliers'
+import dialogProducts from './DialogProducts'
+const { proxy } = getCurrentInstance()
+/** 父组件传参 */
+const props = defineProps({
+	getList: {
+		type: Function,
+		default: () => {}
+	},
+	deliveryMethod: {
+		type: Array,
+		default: []
+	},
+	packagingMethod: {
+		type: Array,
+		default: []
+	}
+})
+const { getList, deliveryMethod, packagingMethod } = toRefs(props)
+/** 字典数组区 */
+/** 表单抽屉 页变量 */
+
+const loading = ref(false)
+const multiple = ref(true)
+const visible = ref(false)
+const editStatus = ref(false)
+const isFullscreen = ref(false)
+const webHost = import.meta.env.VITE_APP_BASE_API
+const form = ref({})
+const formatDetails = ref([])
+const currentDetail = ref({})
+const rules = {
+	supplierName: [{ required: true, message: '外协商名称不能为空', trigger: 'blur' }]
+}
+const emptyDetail = ref({
+	id: null,
+	lotId: null,
+	dayworkId: null,
+	productId: null,
+	productDescription: null,
+	technologicalProcessId: null,
+	technologyVersion: null,
+	originalCarrier: null,
+	originalCarrierCount: null,
+	newCarrier: null,
+	newCarrierCount: null,
+	remark: null
+})
+
+/***********************  方法区  ****************************/
+/** 打开抽屉 */
+function open(id) {
+	reset()
+	visible.value = true
+	if (id) {
+		getOrder(id).then((response) => {
+			form.value = response.data
+			form.value.detail = []
+			editStatus.value = false
+		})
+	} else {
+		editStatus.value = true
+	}
+}
+
+/** 查询表单信息  */
+function getForm() {
+	loading.value = true
+	getOrder(form.value.id).then((response) => {
+		loading.value = false
+		form.value = response.data
+	})
+}
+
+/** 取消按钮 */
+function cancel() {
+	visible.value = false
+	reset()
+}
+
+/** 表单重置 */
+function reset() {
+	form.value = {
+		id: null,
+		tenantId: null,
+		formCode: null,
+		formDate: proxy.parseTime(new Date(), '{y}-{m}-{d}'),
+		supplierId: '0',
+		supplierName: '',
+		deliveryMethod: '0',
+		freightPrice: 0.0,
+		freightAmount: 0.0,
+		packagingMethod: '0',
+		remark: null,
+		details: []
+	}
+	proxy.resetForm('formRef')
+}
+/** 提交按钮 */
+function submitForm() {
+	proxy.$refs['formRef'].validate((valid) => {
+		if (valid) {
+			if (form.value.id != null) {
+				updateOrder(form.value).then((response) => {
+					proxy.$modal.msgSuccess('修改成功')
+					visible.value = false
+					getList.value()
+				})
+			} else {
+				addOrder(form.value).then((response) => {
+					proxy.$modal.msgSuccess('新增成功')
+					visible.value = false
+					getList.value()
+				})
+			}
+		}
+	})
+}
+/***************************** 外协商对话框相关 *****************************/
+// 打开外协商选择对话框
+const handleShowDialogSuppliers = () => {
+	proxy.$refs.dialogSuppliersRef.open()
+}
+// 外协商选择带回
+const handleSingleSelectedSupplier = (data) => {
+	form.value.supplierId = data.id
+	form.value.supplierName = data.name
+}
+
+/***************************** 产品对话框相关 *****************************/
+// 打开产品选择对话框
+const handleShowDialogProducts = () => {
+	proxy.$refs.dialogProductsRef.open()
+}
+// 产品选择带回
+const handleMultipleSelectedProducts = (selection) => {
+	selection.forEach((item) => {
+		const newDetail = {}
+		form.value.details.push(newDetail)
+	})
+}
+
+/***************************** 外协箱子对话框相关 *****************************/
+// 打开外协箱子选择对话框
+const handleShowDialogOutsourceCarriers = () => {}
+// 产品选择带回
+const handleMultipleSelectedOutsourceCarriers = (selection) => {
+	selection.forEach((item) => {
+		const newDetail = {}
+		form.value.details.push(newDetail)
+	})
+}
+
+/** 暴露给父组件的方法 */
+defineExpose({
+	open
+})
+</script>

+ 243 - 0
src/views/business/outsource/index.vue

@@ -0,0 +1,243 @@
+<template>
+	<div class="page-container column-container">
+		<!-- 搜索区 -->
+		<el-form class="list-search-container" :model="queryParams" ref="queryRef" :inline="true">
+			<el-form-item label="单据号:" prop="formCode">
+				<el-input
+					v-model="queryParams.formCode"
+					placeholder="请输入单据号"
+					style="width: 144px"
+					clearable
+					@keyup.enter="handleQuery"
+				/>
+			</el-form-item>
+			<el-form-item label="表单日期:" prop="formDate">
+				<el-date-picker
+					v-model="queryParams.formDate"
+					type="date"
+					style="width: 144px"
+					clearable
+					value-format="YYYY-MM-DD"
+					placeholder="请选择表单日期"
+				>
+				</el-date-picker>
+			</el-form-item>
+			<el-form-item label="外协商名称:" prop="supplierName">
+				<el-input
+					v-model="queryParams.supplierName"
+					placeholder="请输入关键字"
+					style="width: 144px"
+					clearable
+					@keyup.enter="handleQuery"
+				/>
+			</el-form-item>
+			<el-form-item label="送货方式:" prop="deliveryMethod">
+				<el-select v-model="queryParams.deliveryMethod" style="width: 144px" clearable placeholder="请选择">
+					<el-option v-for="dict in delivery_method" :key="dict.value" :label="dict.label" :value="dict.value" />
+				</el-select>
+			</el-form-item>
+			<el-form-item label="带箱方式:" prop="packagingMethod">
+				<el-select v-model="queryParams.packagingMethod" style="width: 144px" clearable placeholder="请选择">
+					<el-option v-for="dict in packaging_method" :key="dict.value" :label="dict.label" :value="dict.value" />
+				</el-select>
+			</el-form-item>
+			<el-form-item>
+				<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+				<el-button icon="Refresh" @click="resetQuery">重置</el-button>
+			</el-form-item>
+		</el-form>
+
+		<!-- 功能按钮区 -->
+		<div class="list-btns-container">
+			<el-button type="primary" icon="Plus" @click="handleAdd" v-hasPermi="['business:outsource:add']">
+				新增
+			</el-button>
+			<el-button
+				type="success"
+				icon="Edit"
+				:disabled="single"
+				@click="handleUpdate"
+				v-hasPermi="['business:outsource:edit']"
+			>
+				修改
+			</el-button>
+			<el-button
+				type="danger"
+				icon="Delete"
+				:disabled="multiple"
+				@click="handleDelete"
+				v-hasPermi="['business:outsource:remove']"
+			>
+				删除
+			</el-button>
+			<el-button type="warning" icon="Download" @click="handleExport" v-hasPermi="['business:outsource:export']">
+				导出
+			</el-button>
+			<!--<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>-->
+		</div>
+
+		<!-- 渲染数据区 -->
+		<div class="el-table-container">
+			<div class="el-table-inner-container">
+				<el-table
+					v-loading="loading"
+					:data="orderList"
+					size="small"
+					border
+					height="100%"
+					@selection-change="handleSelectionChange"
+				>
+					<el-table-column type="selection" width="48" align="center" />
+					<el-table-column label="外协单号" align="center" prop="formCode" width="120" />
+					<el-table-column label="外协日期" align="center" prop="formDate" width="120">
+						<template #default="scope">
+							{{ parseTime(scope.row.formDate, '{y}-{m}-{d}') }}
+						</template>
+					</el-table-column>
+					<el-table-column label="外协商名称" align="center" prop="supplierName" width="320" />
+					<el-table-column label="送货方式" align="center" prop="deliveryMethod" width="120" />
+					<el-table-column label="带箱方式" align="center" prop="packagingMethod" width="120" />
+					<el-table-column label="备注" align="center" prop="remark" />
+					<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="144">
+						<template #default="scope">
+							<el-button
+								link
+								type="warning"
+								icon="Edit"
+								@click="handleUpdate(scope.row)"
+								v-hasPermi="['business:outsource:edit']"
+							>
+								编辑
+							</el-button>
+							<el-button
+								link
+								type="danger"
+								icon="Delete"
+								@click="handleDelete(scope.row)"
+								v-hasPermi="['business:outsource:remove']"
+							>
+								删除
+							</el-button>
+						</template>
+					</el-table-column>
+				</el-table>
+			</div>
+		</div>
+
+		<!-- 分页 -->
+		<pagination
+			v-show="total > 0"
+			:total="total"
+			v-model:page="queryParams.pageNum"
+			v-model:limit="queryParams.pageSize"
+			@pagination="getList"
+		/>
+
+		<!-- 表单 -->
+		<order-form
+			ref="orderRef"
+			:get-list="getList"
+			:delivery-method="delivery_method"
+			:packaging-method="packaging_method"
+		/>
+	</div>
+</template>
+
+<script setup name="Order">
+import { listOrder, delOrder } from '@/api/business/outsourcedOrder'
+import orderForm from './form'
+const { proxy } = getCurrentInstance()
+/** 字典数组区 */
+const { delivery_method } = proxy.useDict('delivery_method')
+const { packaging_method } = proxy.useDict('packaging_method')
+
+const orderList = ref([])
+const loading = ref(true)
+const ids = ref([])
+const single = ref(true)
+const multiple = ref(true)
+const total = ref(0)
+/** 查询对象 */
+const queryParams = ref({
+	pageNum: 1,
+	pageSize: 10,
+	formCode: null,
+	formDate: null,
+	supplierName: null,
+	deliveryMethod: null,
+	packagingMethod: null,
+	freightPrice: null,
+	freightAmount: null
+})
+
+/***********************  方法区  ****************************/
+
+/** 查询外协单主
+带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子列表 */
+function getList() {
+	loading.value = true
+	listOrder(queryParams.value).then((response) => {
+		orderList.value = response.rows
+		total.value = response.total
+		loading.value = false
+	})
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+	queryParams.value.pageNum = 1
+	getList()
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+	proxy.resetForm('queryRef')
+	handleQuery()
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+	ids.value = selection.map((item) => item.id)
+	single.value = selection.length != 1
+	multiple.value = !selection.length
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+	proxy.$refs.orderRef.open()
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+	const id = row.id || ids.value
+	proxy.$refs.orderRef.open(id)
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+	const _ids = row.id || ids.value
+	proxy.$modal
+		.confirm('是否确认删除选中的数据项?')
+		.then(function () {
+			return delOrder(_ids)
+		})
+		.then(() => {
+			getList()
+			proxy.$modal.msgSuccess('删除成功!')
+		})
+		.catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+	proxy.download(
+		'business/order/export',
+		{
+			...queryParams.value
+		},
+		`order_${new Date().getTime()}.xlsx`
+	)
+}
+
+getList()
+</script>

+ 1 - 1
src/views/business/supplier/form.vue

@@ -10,7 +10,7 @@
 					<el-input v-model.trim="form.mnemonicCode" placeholder="请输入料号" />
 				</el-form-item>
 				<el-form-item label="发货方式" prop="deliveryMethod">
-					<el-select v-model="form.deliveryMethod" placeholder="请选择产品状态">
+					<el-select v-model="form.deliveryMethod" placeholder="请选择">
 						<el-option v-for="dict in deliveryMethod" :key="dict.value" :label="dict.label" :value="dict.value - 0" />
 					</el-select>
 				</el-form-item>