ソースを参照

试验,材料取样,接口调试

iZaiZaiA 2 年 前
コミット
dc23a084b1

+ 8 - 0
src/api/modules/other.js

@@ -103,3 +103,11 @@ export const checkCustomFlowUserIsEVisaPermissions = (form, msg = true) => httpA
     method: 'post',
     data: form
 }, msg);
+
+
+//获取用户列表
+export const getUserList = (form, msg = true) => httpApi({
+    url: '/api/blade-manager/contractInfo/get-user-list',
+    method: 'get',
+    params: form
+}, msg);

+ 60 - 0
src/api/modules/tentative/material/sampling.js

@@ -0,0 +1,60 @@
+import {httpApi} from "../../../request/httpApi";
+
+export default {
+    //树数据
+    async queryLazyTree(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-manager/wbsPrivate/lazy-tree',
+            method: 'get',
+            params: form
+        }, msg);
+    },
+    //分页条件查询
+    async queryPage(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/material/sample/page',
+            method: 'get',
+            params: form
+        }, msg);
+    },
+    //进场材料新增或修改
+    async submitForm(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/material/sample/submit',
+            method: 'post',
+            data: form
+        }, msg);
+    },
+    //进场材料批量删除
+    async removeData(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/material/sample/remove',
+            method: 'post',
+            params: form
+        }, msg);
+    },
+    //校验样品编号是否唯一
+    async verification(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/material/sample/verification',
+            method: 'get',
+            params: form
+        }, msg);
+    },
+    //进场材料批量复制
+    async copyData(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/material/sample/copy',
+            method: 'post',
+            data: form
+        }, msg);
+    },
+    //批量打印进场材料Pdf
+    async exportPdf(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/material/sample/export-pdf',
+            method: 'post',
+            params: form
+        }, msg);
+    },
+}

+ 2 - 18
src/views/tentative/material/approach.vue

@@ -351,23 +351,7 @@ const addEditFormModalClose = () => {
 
 //新增/编辑 表单
 const addEditFormRef = ref(null)
-const addEditFormModel = ref({
-    materialType: null,
-    materialPrice: '',
-    materialName: '',
-    materialCount: '',
-    specificationModel: '',
-    calculationUnit: '',
-    materialNumber: '',
-    batchNumber: '',
-    mobilizationDate: null,
-    proposedPosition: '',
-    supplierUnit: '',
-    placeOfProduction: '',
-    productionCertificate: '',
-    qualityInspectionReport: '',
-    otherAccessories: '',
-})
+const addEditFormModel = ref({})
 const addEditFormRules = {
     materialType: {
         required: true,
@@ -448,8 +432,8 @@ const copyTableData = ref([])
 //复制
 const copyTableModal = ref(false)
 const copyTableModalClick = () => {
-    copyTableData.value = deepClone(tableCheckedKeys.value)
     copyTableModal.value = true
+    copyTableData.value = deepClone(tableCheckedKeys.value)
 }
 
 //效验材料编号

+ 172 - 0
src/views/tentative/material/components/TestTree.vue

@@ -0,0 +1,172 @@
+<template>
+    <ElTree class="hc-tree-node tree-line"
+            :class="ui"
+            ref="ElTreeRef"
+            :props="ElTreeProps"
+            :load="ElTreeLoadNode"
+            lazy
+            highlight-current
+            accordion
+            node-key="primaryKeyId"
+            :default-expanded-keys="defaultExpandedCids"
+            @node-click="ElTreeClick"
+            :indent="0">
+        <template #default="{ node, data }">
+            <div class="data-custom-tree-node" :id="`${idPrefix}${data['primaryKeyId']}`">
+                <div class="label" :class="node.level === 1?'level-name':''">{{ node.label }}</div>
+            </div>
+        </template>
+    </ElTree>
+
+</template>
+
+<script setup>
+import {ref,nextTick,watch} from "vue";
+import samplingApi from "~api/tentative/material/sampling"
+import {isItem,getArrValue} from "vue-utils-plus"
+
+//参数
+const props = defineProps({
+    projectId: {
+        type: [String,Number],
+        default: ''
+    },
+    contractId: {
+        type: [String,Number],
+        default: ''
+    },
+    wbsTempId: {
+        type: [String,Number],
+        default: ''
+    },
+    tenantId: {
+        type: [String,Number],
+        default: ''
+    },
+    autoExpandKeys: {
+        type: Array,
+        default: () => ([])
+    },
+    idPrefix: {
+        type: String,
+        default: 'test-tree-'
+    },
+    ui: {
+        type: String,
+        default: ''
+    },
+})
+
+//变量
+const ElTreeRef = ref(null)
+const ElTreeProps = ref({
+    label: 'title',
+    children: 'children',
+    isLeaf: 'hasChildren'
+})
+const TreeExpandKey = ref(props.autoExpandKeys)
+const projectId = ref(props.projectId);
+const contractId = ref(props.contractId);
+const wbsTempId = ref(props.wbsTempId);
+const tenantId = ref(props.tenantId);
+const idPrefix = ref(props.idPrefix);
+
+//监听
+watch(() => [
+    props.autoExpandKeys,
+    props.projectId,
+    props.contractId,
+    props.wbsTempId,
+    props.tenantId,
+    props.idPrefix,
+], ([expandKeys, UserProjectId, UserContractId, UserWbsTempId, UserTenantId, UserIdPrefix]) => {
+    TreeExpandKey.value = expandKeys
+    projectId.value = UserProjectId
+    contractId.value = UserContractId
+    wbsTempId.value = UserWbsTempId
+    tenantId.value = UserTenantId
+    idPrefix.value = UserIdPrefix
+})
+
+//事件
+const emit = defineEmits(['menuTap','nodeTap', 'nodeLoading'])
+
+//树形结构异步加载数据
+const defaultExpandedCids = ref([])
+const ElTreeLoadNode = async (node, resolve) => {
+    let parentId = '0';
+    if (node.level !== 0) {
+        parentId = node?.data?.id
+    }
+    //获取数据
+    const {error, code, data} = await samplingApi.queryLazyTree({
+        wbsId: wbsTempId.value,
+        tenantId: tenantId.value,
+        projectId: projectId.value,
+        parentId,
+    })
+    //处理数据
+    if (!error && code === 200) {
+        let clickKey = '', defaultExpandedArr = [];
+        const keys = TreeExpandKey.value || []
+        const resData = getArrValue(data)
+        for (let i = 0; i < resData.length; i++) {
+            resData[i].hasChildren = !resData[i].hasChildren
+        }
+        if (keys.length > 0) {
+            let lastKey = keys[keys.length-1];
+            for (const item of resData) {
+                //自动展开
+                if (isItem(keys,item?.primaryKeyId)) {
+                    defaultExpandedArr.push(item?.primaryKeyId)
+                }
+                //最后一个,选中点击
+                if (item?.primaryKeyId === lastKey) {
+                    clickKey = item?.primaryKeyId
+                }
+            }
+        } else if (node.level === 0) {
+            defaultExpandedArr.push(resData[0]?.primaryKeyId)
+        }
+        //自动展开
+        defaultExpandedCids.value = defaultExpandedArr
+        if (node.level === 0) {
+            emit('nodeLoading')
+        }
+        resolve(resData)
+        //最后一个,执行点击
+        if (clickKey) {
+            await nextTick(() => {
+                document.getElementById(`${idPrefix.value}${clickKey}`)?.click()
+            })
+        }
+    } else {
+        if (node.level === 0) {
+            emit('nodeLoading')
+        }
+        resolve([])
+    }
+}
+
+//节点被点击
+const ElTreeClick = async (data,node) => {
+    let autoKeysArr = []
+    await getNodeExpandKeys(node, autoKeysArr)
+    const autoKeys = autoKeysArr.reverse()
+    emit('nodeTap', {node, data, keys: autoKeys})
+}
+
+//处理自动展开的节点KEY
+const getNodeExpandKeys = async (node, newKeys) => {
+    const parent = node?.parent ?? []
+    const primaryKeyId = node?.data?.primaryKeyId ?? ''
+    if (primaryKeyId) {
+        newKeys.push(primaryKeyId)
+        await getNodeExpandKeys(parent, newKeys)
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+@import "../../../../styles/app/tree.scss";
+</style>

+ 372 - 101
src/views/tentative/material/sampling.vue

@@ -12,7 +12,7 @@
             </div>
             <div class="hc-tree-box">
                 <el-scrollbar>
-                    <WbsTree :autoExpandKeys="treeAutoExpandKeys" :projectId="projectId" :contractId="contractId" isColor @nodeTap="wbsElTreeClick"/>
+                    <TestTree :autoExpandKeys="treeAutoExpandKeys" :projectId="projectId" :wbsTempId="projectInfo?.referenceWbsTemplateId" :tenantId="userInfo?.tenant_id" @nodeTap="wbsElTreeClick"/>
                 </el-scrollbar>
             </div>
             <!--左右拖动-->
@@ -22,37 +22,37 @@
             <HcCard :scrollbar="false" actionSize="lg">
                 <template #header>
                     <HcTooltip keys="tentative_material_sampling_add">
-                        <el-button type="primary" hc-btn @click="addFormModalClick">
+                        <el-button type="primary" hc-btn :disabled="!primaryKeyId" @click="addFormModalClick">
                             <HcIcon name="add-circle"/>
                             <span>新增</span>
                         </el-button>
                     </HcTooltip>
                     <HcTooltip keys="tentative_material_sampling_edit">
-                        <el-button hc-btn @click="editFormModalClick">
+                        <el-button hc-btn :disabled="tableCheckedKeys.length <= 0" @click="editFormModalClick">
                             <HcIcon name="edit"/>
                             <span>编辑</span>
                         </el-button>
                     </HcTooltip>
                     <HcTooltip keys="tentative_material_sampling_copy">
-                        <el-button hc-btn @click="copyTableModalClick">
+                        <el-button hc-btn :disabled="tableCheckedKeys.length <= 0" @click="copyTableModalClick">
                             <HcIcon name="file-copy-2"/>
                             <span>复制</span>
                         </el-button>
                     </HcTooltip>
                     <HcTooltip keys="tentative_material_sampling_del">
-                        <el-button hc-btn @click="delModalClick">
+                        <el-button hc-btn :disabled="tableCheckedKeys.length <= 0" @click="delModalClick">
                             <HcIcon name="delete-bin-2"/>
                             <span>删除</span>
                         </el-button>
                     </HcTooltip>
                     <HcTooltip keys="tentative_material_sampling_printer">
-                        <el-button hc-btn>
+                        <el-button hc-btn :disabled="tableCheckedKeys.length <= 0" :loading="printerLoading" @click="printerClick">
                             <HcIcon name="printer"/>
                             <span>打印</span>
                         </el-button>
                     </HcTooltip>
                     <HcTooltip keys="tentative_material_sampling_import">
-                        <el-button hc-btn @click="importModalClick">
+                        <el-button hc-btn :disabled="!primaryKeyId" @click="importModalClick">
                             <HcIcon name="folder-upload"/>
                             <span>导入</span>
                         </el-button>
@@ -83,71 +83,73 @@
         <HcDialog :show="addEditFormModal" title="新增/编辑 样品信息" widths="50rem" isRowFooter @close="addEditFormModalClose">
             <el-form ref="addEditFormRef" :model="addEditFormModel" :rules="addEditFormRules" label-width="auto" size="large">
                 <div class="hc-form-item">
-                    <el-form-item label="样品名称" prop="key1">
-                        <el-input v-model="addEditFormModel.key1"/>
+                    <el-form-item label="样品名称" prop="materialName">
+                        <el-input v-model="addEditFormModel.materialName"/>
                     </el-form-item>
-                    <el-form-item label="进场日期" prop="key9">
-                        <el-date-picker type="date" v-model="addEditFormModel.key9" class="block" value-format="YYYY-MM-DD" :clearable="false"/>
+                    <el-form-item label="进场日期">
+                        <el-date-picker type="date" v-model="addEditFormModel.mobilizationDate" class="block" value-format="YYYY-MM-DD" :clearable="false"/>
                     </el-form-item>
                 </div>
                 <div class="hc-form-item">
-                    <el-form-item label="样品编号" prop="key3">
-                        <el-input v-model="addEditFormModel.key3"/>
+                    <el-form-item label="样品编号" prop="specificationNumber">
+                        <el-input v-model="addEditFormModel.specificationNumber"/>
                     </el-form-item>
-                    <el-form-item label="取样日期" prop="key4">
-                        <el-date-picker type="date" v-model="addEditFormModel.key4" class="block" value-format="YYYY-MM-DD" :clearable="false"/>
+                    <el-form-item label="取样日期">
+                        <el-date-picker type="date" v-model="addEditFormModel.samplingDate" class="block" value-format="YYYY-MM-DD" :clearable="false"/>
                     </el-form-item>
                 </div>
                 <div class="hc-form-item">
-                    <el-form-item label="规格型号" prop="key5">
-                        <el-input v-model="addEditFormModel.key5"/>
+                    <el-form-item label="规格型号">
+                        <el-input v-model="addEditFormModel.specificationModel"/>
                     </el-form-item>
-                    <el-form-item label="取样地点" prop="key6">
-                        <el-input v-model="addEditFormModel.key6"/>
+                    <el-form-item label="取样地点">
+                        <el-input v-model="addEditFormModel.samplingLocation"/>
                     </el-form-item>
                 </div>
                 <div class="hc-form-item">
-                    <el-form-item label="试样数量" prop="key7">
-                        <el-input v-model="addEditFormModel.key7"/>
+                    <el-form-item label="试样数量">
+                        <el-input v-model="addEditFormModel.materialCount"/>
                     </el-form-item>
-                    <el-form-item label="是否外委" prop="key8">
-                        <el-radio-group v-model="addEditFormModel.key8" size="large">
+                    <el-form-item label="是否外委">
+                        <el-radio-group v-model="addEditFormModel.isOutsourcing" size="large">
                             <el-radio :label="1">是</el-radio>
-                            <el-radio :label="2">否</el-radio>
+                            <el-radio :label="0">否</el-radio>
                         </el-radio-group>
                     </el-form-item>
                 </div>
                 <div class="hc-form-item">
-                    <el-form-item label="代表数量" prop="key9">
-                        <el-input v-model="addEditFormModel.key9"/>
+                    <el-form-item label="代表数量">
+                        <el-input v-model="addEditFormModel.representativeCount"/>
                     </el-form-item>
-                    <el-form-item label="供应商" prop="key10">
-                        <el-input v-model="addEditFormModel.key10"/>
+                    <el-form-item label="供应商">
+                        <el-input v-model="addEditFormModel.supplierUnit"/>
                     </el-form-item>
                 </div>
                 <div class="hc-form-item">
-                    <el-form-item label="计算单位" prop="key11">
-                        <el-input v-model="addEditFormModel.key11"/>
+                    <el-form-item label="计算单位">
+                        <el-input v-model="addEditFormModel.calculationUnit"/>
                     </el-form-item>
-                    <el-form-item label="生产批号" prop="key12">
-                        <el-input v-model="addEditFormModel.key12"/>
+                    <el-form-item label="生产批号">
+                        <el-input v-model="addEditFormModel.batchNumber"/>
                     </el-form-item>
                 </div>
                 <div class="hc-form-item">
-                    <el-form-item label="取样人" prop="key13">
-                        <el-input v-model="addEditFormModel.key13"/>
+                    <el-form-item label="取样人">
+                        <el-select v-model="addEditFormModel.userId" block>
+                            <el-option v-for="item in userListData" :label="item['name']" :value="item['id']"/>
+                        </el-select>
                     </el-form-item>
-                    <el-form-item label="拟用部位" prop="key14">
-                        <el-input v-model="addEditFormModel.key14"/>
+                    <el-form-item label="拟用部位">
+                        <el-input v-model="addEditFormModel.proposedPosition"/>
                     </el-form-item>
                 </div>
-                <el-form-item label="样品描述" prop="key15">
-                    <el-input v-model="addEditFormModel.key15"/>
+                <el-form-item label="样品描述">
+                    <el-input v-model="addEditFormModel.sampleDescription"/>
                 </el-form-item>
             </el-form>
             <template #leftRowFooter>
                 <HcTooltip keys="tentative_material_sampling_links">
-                    <el-button type="primary" hc-btn @click="linksApproachModalClick">
+                    <el-button type="primary" hc-btn @click="linksApproachModalClick(addEditFormModel.mobilizationId)">
                         <HcIcon name="links"/>
                         <span>关联进场材料</span>
                     </el-button>
@@ -166,24 +168,39 @@
         </HcDialog>
 
         <!--关联进场材料-->
-        <HcDialog :show="linksApproachModal" title="关联进场材料信息" widths="60%" isTable saveText="确认" @close="linksApproachModalClose" @save="linksApproachModalSave">
+        <HcDialog :show="linksApproachModal" title="关联进场材料信息" widths="60%" isTable isRowFooter @close="linksApproachModalClose">
             <HcTable :column="linksApproachTableColumn" :datas="linksApproachTableData" :loading="linksApproachTableLoading" :isIndex="false">
+                <template #materialType="{row}">{{getRowTableMaterialType(row['materialType'])}}</template>
                 <template #action="{row}">
                     <HcTooltip keys="tentative_material_approach_annex">
-                        <el-button type="primary" size="small" plain @click="linksApproachRow(row)">关联</el-button>
+                        <el-button type="primary" size="small" plain @click="cancelApproachRow(row)" v-if="mobilizationId === row.id">取消关联</el-button>
+                        <el-button type="primary" size="small" plain @click="linksApproachRow(row)" v-else>关联</el-button>
                     </HcTooltip>
                 </template>
             </HcTable>
+            <template #leftRowFooter>
+                <HcPages :pages="ApproachSearchForm" @change="linksApproachPageChange"/>
+            </template>
+            <template #rightRowFooter>
+                <el-button size="large" @click="linksApproachModalClose">
+                    <HcIcon name="close"/>
+                    <span>取消</span>
+                </el-button>
+                <el-button type="primary" hc-btn @click="linksApproachModalSave">
+                    <HcIcon name="check"/>
+                    <span>确定</span>
+                </el-button>
+            </template>
         </HcDialog>
 
         <!--复制样品登记信息-->
         <HcDialog :show="copyTableModal" title="复制样品登记信息" widths="60rem" isTable :loading="copyTableLoading" @close="copyTableModalClose" @save="copyTableClick">
             <HcTable :column="copyTableColumn" :datas="copyTableData">
-                <template #key1="{row}">
-                    <el-input v-model="row.key1" placeholder="请输入材料编号"/>
+                <template #materialNumber="{row}">
+                    <el-input v-model="row.specificationNumber" :class="row.isSpecificationNumber?'is-error':''" placeholder="请输入样品编号" @blur="specificationNumberBlur(row)"/>
                 </template>
-                <template #action="{row}">
-                    <el-button type="danger" size="small" plain>删除</el-button>
+                <template #action="{index}">
+                    <el-button type="danger" size="small" plain @click="specificationNumberDel(index)">删除</el-button>
                 </template>
             </HcTable>
         </HcDialog>
@@ -215,12 +232,18 @@
 <script setup>
 import {ref, watch, onMounted} from "vue";
 import {useAppStore} from "~src/store";
-import WbsTree from "../../data-fill/components/WbsTree.vue"
+import TestTree from "./components/TestTree.vue"
 import {getStoreData, setStoreData} from '~src/utils/storage'
 import HcDragUpload from "./components/HcDragUpload.vue"
+import samplingApi from "~api/tentative/material/sampling"
+import approachApi from "~api/tentative/material/approach";
+import {deepClone, formValidate, getArrValue, getIndex} from "vue-utils-plus";
+import {getDictionary, getUserList} from "~api/other";
+
 
 //变量
 const useAppState = useAppStore()
+const userInfo = ref(useAppState.getUserInfo);
 const projectId = ref(useAppState.getProjectId);
 const contractId = ref(useAppState.getContractId);
 const projectInfo = ref(useAppState.getProjectInfo);
@@ -234,16 +257,47 @@ watch(() => [
 })
 
 //自动展开缓存
-const treeAutoExpandKeys = ref(getStoreData('wbsTreeExpandKeys') || [])
+const treeAutoExpandKeys = ref(getStoreData('testTreeExpandKeys') || [])
 
 //渲染完成
 onMounted(() => {
-
+    getUserListData()
+    getMaterialType()
 })
 
-//搜索表单
-const searchForm = ref({betweenTime: null, queryValue: null, current: 1, size: 20, total: 0})
+//获取材料类型
+const typeData = ref([])
+const getMaterialType = async () => {
+    const { data } = await getDictionary({
+        code: 'material_type'
+    })
+    typeData.value = getArrValue(data)
+}
 
+//获取材料类型
+const getRowTableMaterialType = (type) => {
+    if (type > 0) {
+        const nodeData = typeData.value
+        const index = getIndex(nodeData, 'dictKey', type)
+        return nodeData[index]?.dictValue ?? type
+    } else {
+        return ''
+    }
+}
+
+
+//获取用户列表
+const userListData = ref([])
+const getUserListData = async () => {
+    const { data } = await getUserList()
+    userListData.value = getArrValue(data)
+}
+
+//搜索表单
+const searchForm = ref({
+    startTime: null, endTime: null, queryValue: null, nodeId: '',
+    current: 1, size: 20, total: 0
+})
 
 //树相关的变量
 const primaryKeyId = ref('')
@@ -257,19 +311,21 @@ const wbsElTreeClick = ({node, data, keys}) => {
     primaryKeyId.value = data['primaryKeyId'] || ''
     //缓存自动展开
     treeAutoExpandKeys.value = keys
-    setStoreData('wbsTreeExpandKeys',keys)
+    setStoreData('testTreeExpandKeys',keys)
     //改变搜索表单数据
-    //searchForm.value.wbsId = data['contractIdRelation'] ? data['id'] : data['primaryKeyId']
-    //searchForm.value.contractIdRelation = data['contractIdRelation']
+    searchForm.value.nodeId = data['primaryKeyId'] || ''
     searchForm.value.current = 1;
     getTableData()
 }
 
 //日期时间被选择
 const betweenTime = ref(null)
-const betweenTimeUpdate = ({arr,query}) => {
+const betweenTimeUpdate = ({arr}) => {
     betweenTime.value = arr
-    searchForm.value.betweenTime = query
+    if (arr.length > 0) {
+        searchForm.value.startTime = arr[0]
+        searchForm.value.endTime = arr[1]
+    }
 }
 
 //回车搜索
@@ -296,24 +352,42 @@ const pageChange = ({current, size}) => {
 //表格数据
 const tableRef = ref(null)
 const tableColumn = ref([
-    {key:'key1', name: '取样名称'},
-    {key:'key2', name: '取样日期'},
-    {key:'key3', name: '样品编号'},
-    {key:'key4', name: '规格型号'},
-    {key:'key5', name: '试样数量'},
-    {key:'key6', name: '计算单位'},
-    {key:'key7', name: '拟用部位'},
-    {key:'key8', name: '代表数量'},
-    {key:'key9', name: '取样人'}
+    {key:'materialName', name: '取样名称'},
+    {key:'samplingDate', name: '取样日期'},
+    {key:'specificationNumber', name: '样品编号'},
+    {key:'specificationModel', name: '规格型号'},
+    {key:'materialCount', name: '试样数量'},
+    {key:'calculationUnit', name: '计算单位'},
+    {key:'proposedPosition', name: '拟用部位'},
+    {key:'representativeCount', name: '代表数量'},
+    {key:'userName', name: '取样人'}
 ])
 
 //获取数据
 const tableLoading = ref(false)
-const tableData = ref([
-    {}
-])
+const tableData = ref([])
 const getTableData = async () => {
-
+    const nodeId = primaryKeyId.value
+    if (nodeId) {
+        tableLoading.value = true
+        const { error, code, data } = await samplingApi.queryPage({
+            projectId: projectId.value,
+            contractId: contractId.value,
+            nodeId,
+            ...searchForm.value,
+        })
+        //处理数据
+        tableLoading.value = false
+        if (!error && code === 200) {
+            tableData.value = getArrValue(data['records'])
+            searchForm.value.total = data.total || 0
+        } else {
+            tableData.value = []
+            searchForm.value.total = 0
+        }
+    } else {
+        window?.$message?.warning('请先选择一个树节点')
+    }
 }
 
 //多选
@@ -324,14 +398,26 @@ const tableSelection = (rows) => {
     })
 }
 
-
-//新增/编辑 材料进场
+//新增
 const addEditFormModal = ref(false)
 const addFormModalClick = () => {
+    addEditFormModel.value = {
+        isOutsourcing: 0,
+        mobilizationId: '',
+        nodeId: primaryKeyId.value,
+        userId: userInfo.value.user_id
+    }
     addEditFormModal.value = true
 }
+//编辑
 const editFormModalClick = () => {
-    addEditFormModal.value = true
+    const keys = tableCheckedKeys.value
+    if (keys.length === 1) {
+        addEditFormModel.value = keys[0]
+        addEditFormModal.value = true
+    } else if (keys.length > 1) {
+        window?.$message?.warning('只能选择一条数据编辑')
+    }
 }
 const addEditFormModalClose = () => {
     addEditFormModal.value = false
@@ -341,41 +427,99 @@ const addEditFormModalClose = () => {
 const addEditFormRef = ref(null)
 const addEditFormModel = ref({})
 const addEditFormRules = {
-    key1: {
+    materialName: {
         required: true,
         trigger: 'blur',
-        message: "请输入"
+        message: "请输入样品名称"
     },
-    key3: {
+    specificationNumber: {
         required: true,
-        trigger: 'blur',
-        message: "请输入"
+        validator: async (rule, value, callback) => {
+            if (!value) {
+                callback(new Error('请输入样品编号'))
+            } else {
+                const ver = await verification(value)
+                if (!ver) {
+                    callback(new Error('样品编号必须是惟一的'))
+                } else {
+                    callback()
+                }
+            }
+        },
+        trigger: 'blur'
     },
 }
 
+//校验材料编号是否唯一
+const verification = async (val) => {
+    const { error, code, data } = await samplingApi.verification({
+        projectId: projectId.value,
+        contractId: contractId.value,
+        specificationNumber: val,
+    })
+    if (!error && code === 200) {
+        return !data
+    } else {
+        return false
+    }
+}
+
 //新增/编辑 保存
 const addEditFormLoading = ref(false)
-const addEditFormClick = () => {
-
+const addEditFormClick = async () => {
+    const validate = await formValidate(addEditFormRef.value)
+    if (validate) {
+        addEditFormLoading.value = true
+        const { error, code } = await samplingApi.submitForm({
+            ...addEditFormModel.value,
+            projectId: projectId.value,
+            contractId: contractId.value
+        })
+        //处理数据
+        addEditFormLoading.value = false
+        if (!error && code === 200) {
+            window?.$message?.success('操作成功')
+            addEditFormModal.value = false
+            await getTableData()
+        }
+    }
 }
 
+
+//复制表格
+const copyTableColumn = ref([
+    {key:'materialName', name: '样品名称'},
+    {key:'specificationNumber', name: '样品编号'},
+    {key:'action', name: '操作', width: 100},
+])
+const copyTableData = ref([])
+
 //复制
 const copyTableModal = ref(false)
-
 const copyTableModalClick = () => {
     copyTableModal.value = true
+    copyTableData.value = deepClone(tableCheckedKeys.value)
 }
 
-//复制表格
-const copyTableColumn = ref([
-    {key:'key3', name: '样品名称'},
-    {key:'key1', name: '样品编号'},
-    {key:'action', name: '操作', width: 100},
-])
-const copyTableData = ref([
-    {key3: '名称', key1: '编号...'},
-    {key3: '名称1', key1: '编号1...'},
-])
+//效验材料编号
+const specificationNumberBlur = async (row) => {
+    const number = row?.specificationNumber ?? ''
+    if (number) {
+        const ver = await verification(number)
+        row.isSpecificationNumber = !ver
+    } else {
+        row.isSpecificationNumber = true
+    }
+}
+
+//删除
+const specificationNumberDel = (index) => {
+    copyTableData.value.splice(index, 1);
+    const rows = copyTableData.value
+    if (rows.length <= 0) {
+        copyTableModal.value = false
+    }
+}
 
 const copyTableModalClose = () => {
     copyTableModal.value = false
@@ -385,6 +529,38 @@ const copyTableModalClose = () => {
 const copyTableLoading = ref(false)
 const copyTableClick = () => {
     copyTableModal.value = false
+    const rows = copyTableData.value
+    if (rows.length > 0) {
+        //判断是否满足条件
+        const result = rows.every(({isSpecificationNumber})=> {
+            return isSpecificationNumber === false
+        })
+        //判断状态
+        if (result) {
+            for (let i = 0; i < rows.length; i++) {
+                rows[i].dataNumber = i
+            }
+            tableCopyData(rows)
+        } else {
+            window.$message?.warning('请先完善材料编号')
+        }
+    } else {
+        window.$message?.warning('请先在列表勾选要复制的数据')
+        copyTableModal.value = false
+    }
+}
+
+//复制数据请求
+const tableCopyData = async (rows) => {
+    copyTableLoading.value = true
+    const { error, code } = await samplingApi.copyData(rows)
+    //处理数据
+    copyTableLoading.value = false
+    if (!error && code === 200) {
+        window?.$message?.success('操作成功')
+        copyTableModal.value = false
+        await getTableData()
+    }
 }
 
 //删除
@@ -396,12 +572,55 @@ const delModalClick = () => {
         type: 'warning',
         callback: (action) => {
             if (action === 'confirm') {
-                //removeContractTreeNode()
+                tableRemoveData()
             }
         }
     })
 }
 
+//批量删除
+const tableRemoveData = async () => {
+    const rows = tableCheckedKeys.value
+    if (rows.length > 0 ) {
+        const ids = rowsToId(rows)
+        //删除请求
+        const { error, code } = await samplingApi.removeData({
+            projectId: projectId.value,
+            contractId: contractId.value,
+            ids: ids,
+        })
+        //处理数据
+        if (!error && code === 200) {
+            window?.$message?.success('操作成功')
+            searchClick()
+        }
+    }
+}
+
+//打印
+const printerLoading = ref(false)
+const printerClick = async () => {
+    const rows = tableCheckedKeys.value
+    if (rows.length > 0 ) {
+        printerLoading.value = true
+        const ids = rowsToId(rows)
+        //删除请求
+        const { error, code, data } = await samplingApi.exportPdf({
+            projectId: projectId.value,
+            contractId: contractId.value,
+            ids: ids,
+        })
+        //处理数据
+        printerLoading.value = false
+        if (!error && code === 200) {
+            console.log(data)
+            //window?.$message?.success('操作成功')
+            //searchClick()
+        }
+    }
+}
+
+
 //导入
 const importModal = ref(false)
 const importModalClick = () => {
@@ -422,32 +641,84 @@ const importModalClose = () => {
 
 //关联进场材料
 const linksApproachModal = ref(false)
-const linksApproachModalClick = (row) => {
+const ApproachSearchForm = ref({
+    current: 1, size: 20, total: 0
+})
+const mobilizationId = ref('')
+const linksApproachModalClick = (mId) => {
+    mobilizationId.value = mId ?? ''
+    ApproachSearchForm.value.current = 1;
     linksApproachModal.value = true
+    getApproachTableData()
+}
+
+//分页被点击
+const linksApproachPageChange = ({current, size}) => {
+    ApproachSearchForm.value.current = current
+    ApproachSearchForm.value.size = size
+    getTableData()
 }
 
 //关联进场材料数据
 const linksApproachTableColumn = ref([
-    {key:'key1', name: '材料编号'},
-    {key:'key2', name: '进场日期'},
-    {key:'key3', name: '材料名称'},
-    {key:'key4', name: '材料类型'},
-    {key:'key5', name: '规格型号'},
-    {key:'key6', name: '供应商单位'},
-    {key:'key7', name: '拟用部位'},
-    {key:'key8', name: '记录人'},
+    {key:'materialNumber', name: '材料编号'},
+    {key:'mobilizationDate', name: '进场日期'},
+    {key:'materialName', name: '材料名称'},
+    {key:'materialType', name: '材料类型'},
+    {key:'specificationModel', name: '规格型号'},
+    {key:'supplierUnit', name: '供应商单位'},
+    {key:'proposedPosition', name: '拟用部位'},
+    {key:'userName', name: '记录人'},
     {key:'action', name: '操作', width: 100, fixed: 'right', align: 'center'},
 ])
 const linksApproachTableData = ref([])
+
+//获取进场材料数据
 const linksApproachTableLoading = ref(false)
+const getApproachTableData = async () => {
+    linksApproachTableLoading.value = true
+    const { error, code, data } = await approachApi.queryPage({
+        projectId: projectId.value,
+        contractId: contractId.value,
+        ...ApproachSearchForm.value,
+    })
+    //处理数据
+    linksApproachTableLoading.value = false
+    if (!error && code === 200) {
+        linksApproachTableData.value = getArrValue(data['records'])
+        ApproachSearchForm.value.total = data.total || 0
+    } else {
+        linksApproachTableData.value = []
+        ApproachSearchForm.value.total = 0
+    }
+}
 
 //关联
 const linksApproachRow = (row) => {
-
+    const form = addEditFormModel.value;
+    form.materialName = row.materialName ?? ''              //样品名称
+    form.mobilizationDate = row.mobilizationDate ?? null    //进场日期
+    form.specificationNumber = row.materialNumber ?? ''     //样品编号
+    form.specificationModel = row.specificationModel ?? ''  //规格型号
+    form.supplierUnit = row.supplierUnit ?? ''              //供应商
+    form.calculationUnit = row.calculationUnit ?? ''        //计算单位
+    form.batchNumber = row.batchNumber ?? ''                //生产批号
+    form.proposedPosition = row.proposedPosition ?? ''      //拟用部位
+    form.mobilizationId = row.id                            //关联ID
+    //更新数据
+    addEditFormModel.value = form
+    mobilizationId.value = row.id //关联ID
+}
+//取消关联
+const cancelApproachRow = (row) => {
+    if (row.id === mobilizationId.value) {
+        addEditFormModel.value.mobilizationId = ''
+        mobilizationId.value = ''
+    }
 }
 
 const linksApproachModalSave = () => {
-
+    linksApproachModal.value = false
 }
 
 //关闭关联进场材料