Selaa lähdekoodia

feat: ✨ 完成合同管理与合同详情

@sun-chaoqun 2 vuotta sitten
vanhempi
commit
0acd16359d

+ 4 - 0
README.md

@@ -29,3 +29,7 @@ https://6b87x3.axshare.com/#id=s9uw1m&p=%E6%88%91%E7%9A%84%E5%8A%A0%E7%8F%AD&g=1
 ### 待优化部分
 
 请假选择完开始结束自动算出小时
+
+销售合同(销售): 通过后屏蔽掉编辑、删除
+
+合同详情:查看 SN 未做

+ 3 - 0
src/api/storehouse/index.ts

@@ -71,3 +71,6 @@ export const Storehouse_Contract_Add = (params: any) => $http.post('/testapi/sto
 export const Storehouse_Contract_Edit = (params: any) => $http.post('/testapi/storage/Contract/Edit', params)
 // 删除
 export const Storehouse_Contract_Del = (params: any) => $http.post('/testapi/storage/Contract/Del', params)
+// 产品列表
+export const Storehouse_Contract_Product_List = (params: any) =>
+  $http.post('/testapi/storage/Contract/Product_List', params)

+ 7 - 2
src/layouts/Header/Breadcrumb.vue

@@ -12,13 +12,14 @@ const breadcrumbList: any = computed(() => {
     return all.some((item: any) => item['path'] == next['path']) ? all : [...all, next]
   }, [])
 })
-// console.log(breadcrumbList)
+console.log(breadcrumbList)
 const isUnicode = (val: string | undefined) => {
   if (!val) return false
   return !/ue/g.test(val)
 }
 
 const onBreadcrumbClick = (item: any, index: number) => {
+  if (item.meta.routerView) return
   if (index !== breadcrumbList.value.length - 1) router.push(item.path)
 }
 </script>
@@ -27,7 +28,11 @@ const onBreadcrumbClick = (item: any, index: number) => {
   <div class="breadcrumb-box">
     <el-breadcrumb :separator-icon="ArrowRight">
       <transition-group appear name="breadcrumb">
-        <el-breadcrumb-item v-for="(item, index) in breadcrumbList" :key="item.path">
+        <el-breadcrumb-item
+          v-for="(item, index) in breadcrumbList"
+          :key="item.path"
+          :class="{ cursor: item.meta.routerView }"
+        >
           <div class="el-breadcrumb__inner is-link" @click="onBreadcrumbClick(item, index)">
             <el-icon class="breadcrumb-icon" v-if="isUnicode(item.meta.icon as string)">
               <component :is="item.meta.icon"></component>

+ 6 - 0
src/layouts/Header/Notice.vue

@@ -0,0 +1,6 @@
+<script setup lang="ts"></script>
+<template>
+  <div class="notice"></div>
+</template>
+
+<style scoped></style>

+ 1 - 0
src/router/index.ts

@@ -19,6 +19,7 @@ router.beforeEach(async (to, from, next) => {
   title && (document.title = title as string)
 
   if (store.GET_User_tokey && to.path !== '/login') {
+    console.log(to.path)
     if (!store.GET_Flat_Menu.length) {
       await initDynamicRouter()
       return next({ ...to, replace: true })

+ 13 - 4
src/router/modules/staticRouter.ts

@@ -46,12 +46,13 @@ export const staticRouter: RouteRecordRaw[] = [
         }
       },
       {
-        path: '/contract',
-        name: 'Contract',
+        path: '/saleMange',
+        name: 'SaleMange',
         component: () => import('@/views/storehouse/sales/index.vue'),
-        redirect: '/contract',
+        // redirect: '/contract',
         meta: {
-          title: '合同管理'
+          routerView: true,
+          title: '销售管理'
         },
         children: [
           {
@@ -69,6 +70,14 @@ export const staticRouter: RouteRecordRaw[] = [
             meta: {
               title: '合同详情'
             }
+          },
+          {
+            path: '/contractSale',
+            name: 'ContractSale',
+            component: () => import('@/views/storehouse/sales/ContractSale.vue'),
+            meta: {
+              title: '合同详情(销售)'
+            }
           }
         ]
       },

+ 24 - 10
src/views/Login.vue

@@ -1,13 +1,15 @@
 <script setup lang="ts">
 import { reactive, ref } from 'vue'
+import { fnMd5 } from '@/utils/common'
+import { useRouter } from 'vue-router'
+import { GlobalStore } from '@/stores/index'
 import { ElNotification } from 'element-plus'
-import type { FormInstance, FormRules } from 'element-plus'
 import type { InLogin } from '@/typings/config'
-import { User, View, Lock, Hide } from '@element-plus/icons-vue'
 import { Login_verification } from '@/api/user/index'
-import { useRouter } from 'vue-router'
-import { GlobalStore } from '@/stores/index'
-import { fnMd5 } from '@/utils/common'
+import type { FormInstance, FormRules } from 'element-plus'
+import { View, Lock, Hide, UserFilled } from '@element-plus/icons-vue'
+
+const loading = ref(false)
 const router = useRouter()
 const globalStore = GlobalStore()
 const ruleFormRef = ref<FormInstance>()
@@ -33,6 +35,7 @@ const submitForm = (formEl: FormInstance | undefined) => {
   if (!formEl) return
   formEl.validate(async valid => {
     if (valid) {
+      loading.value = true
       let res: any = {}
       res = await Login_verification({ bzd_username: ruleForm.username, bzd_password: fnMd5(ruleForm.password) })
       if (res.Code === 200) {
@@ -44,6 +47,9 @@ const submitForm = (formEl: FormInstance | undefined) => {
           message: '欢迎进入宝智达ERP系统!',
           position: 'bottom-right'
         })
+        setTimeout(() => {
+          loading.value = false
+        }, 1000)
       }
     } else {
       return false
@@ -65,11 +71,17 @@ const changeType = () => {
         <span>ShenZhen Baozhida Technology ERP. system</span>
       </div>
       <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules">
-        <el-form-item label="账号:" prop="username">
-          <el-input v-model="ruleForm.username" type="text" :prefix-icon="User" />
+        <el-form-item prop="username">
+          <el-input v-model="ruleForm.username" type="text" :prefix-icon="UserFilled" placeholder="请输入账号" />
         </el-form-item>
-        <el-form-item label="密码:" prop="password">
-          <el-input v-model="ruleForm.password" :type="passType" :prefix-icon="Lock" autocomplete="off">
+        <el-form-item prop="password">
+          <el-input
+            v-model="ruleForm.password"
+            :type="passType"
+            :prefix-icon="Lock"
+            autocomplete="off"
+            placeholder="请输入密码"
+          >
             <template #suffix>
               <span class="view">
                 <el-icon v-if="passType === 'password'" class="el-input__icon" @click="changeType">
@@ -83,7 +95,9 @@ const changeType = () => {
           </el-input>
         </el-form-item>
         <el-form-item>
-          <el-button class="submit" type="primary" @click.enter="submitForm(ruleFormRef)">登录</el-button>
+          <el-button class="submit" type="primary" :loading="loading" @click.enter="submitForm(ruleFormRef)"
+            >登录</el-button
+          >
         </el-form-item>
       </el-form>
     </div>

+ 25 - 16
src/views/storehouse/sales/Contract.vue

@@ -1,13 +1,15 @@
 <script setup lang="ts">
-import { Storehouse_Contract_List, Storehouse_IotCard_Del } from '@/api/storehouse/index'
 import { GlobalStore } from '@/stores/index'
 import { ref, reactive, nextTick } from 'vue'
 import ContractForm from './ContractForm.vue'
+import { useRouter } from 'vue-router'
 import { ElMessageBox, ElMessage } from 'element-plus'
 import TableBase from '@/components/TableBase/index.vue'
 import { Edit, Delete, Finished, View } from '@element-plus/icons-vue'
 import type { ColumnProps } from '@/components/TableBase/interface/index'
+import { Storehouse_Contract_List, Storehouse_Contract_Del } from '@/api/storehouse/index'
 
+const router = useRouter()
 const globalStore = GlobalStore()
 const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
 const ContractFormRef = ref<InstanceType<typeof ContractForm> | null>(null)
@@ -18,7 +20,7 @@ const columns: ColumnProps[] = [
   { prop: 'T_customer', label: '客户名称' },
   { prop: 'T_State', label: '状态', name: 'T_State' },
   { prop: 'T_out', label: '是否出库', name: 'T_out' },
-  { prop: 'T_type', label: '更新时间' },
+  { prop: 'T_date', label: '更新时间' },
   { prop: 'operation', label: '操作', width: 260, fixed: 'right' }
 ]
 
@@ -27,16 +29,19 @@ const openContractFormDrawer = (type: string, row?: any) => {
 }
 
 const updateOnTableList = () => TableRef.value?.getTableList()
-
+// 审核
+const processContract = (id: string) => {
+  router.push({ name: 'ContractDetail', params: { id } })
+}
 // 删除
 const UserDelete = (row: any) => {
-  ElMessageBox.confirm('您确定要删除该物联网卡号吗?', '警告', {
+  ElMessageBox.confirm('您确定要删除该销售合同吗?', '警告', {
     confirmButtonText: '确定',
     cancelButtonText: '取消',
     type: 'warning'
   })
     .then(async () => {
-      const res: any = await Storehouse_IotCard_Del({ User_tokey: globalStore.GET_User_tokey, T_id: row.Id })
+      const res: any = await Storehouse_Contract_Del({ User_tokey: globalStore.GET_User_tokey, T_number: row.T_number })
       if (res.Code === 200) {
         ElMessage.success('删除成功!')
         nextTick(() => {
@@ -95,8 +100,8 @@ const searchHandle = () => {
         </div>
       </template>
       <template #T_State="{ row }">
-        <el-tag v-if="row.T_State === 2" type="success" effect="dark"> 已通过 </el-tag>
-        <el-tag v-else-if="row.T_State === 1" type="warning" effect="dark"> 未通过 </el-tag>
+        <el-tag v-if="row.T_State === 1" type="success" effect="dark"> 已通过 </el-tag>
+        <el-tag v-else-if="row.T_State === 2" type="warning" effect="dark"> 未通过 </el-tag>
         <el-tag v-else type="danger" effect="dark"> 待审核 </el-tag>
       </template>
       <template #T_out="{ row }">
@@ -104,19 +109,23 @@ const searchHandle = () => {
           {{ row.T_out === 2 ? '已出库' : '已全部出库' }}
         </el-tag>
         <el-tag v-else-if="row.T_State === 1" type="warning" effect="dark"> 未出库 </el-tag>
-        <el-tag v-else type="danger" effect="dark"> - </el-tag>
+        <el-tag v-else type="danger" effect="dark"> --- </el-tag>
       </template>
       <template #right="{ row }">
-        <el-button :disabled="row.T_State === 2" link type="warning" size="small" :icon="Finished">审核</el-button>
-        <el-button :disabled="row.T_State === 2" link type="primary" size="small" :icon="Edit" @click="UserDelete(row)"
-          >编辑</el-button
+        <el-button
+          :disabled="row.T_State !== 3"
+          link
+          type="warning"
+          size="small"
+          :icon="Finished"
+          @click="processContract(row.T_number)"
+          >审核</el-button
         >
-        <el-button :disabled="row.T_State === 2" link type="success" size="small" :icon="View" @click="UserDelete(row)"
-          >详情</el-button
-        >
-        <el-button :disabled="row.T_State === 2" link type="danger" size="small" :icon="Delete" @click="UserDelete(row)"
-          >删除</el-button
+        <el-button link type="primary" size="small" :icon="Edit" @click="openContractFormDrawer('edit', row)"
+          >编辑</el-button
         >
+        <el-button link type="success" size="small" :icon="View" @click="processContract(row.T_number)">详情</el-button>
+        <el-button link type="danger" size="small" :icon="Delete" @click="UserDelete(row)">删除</el-button>
       </template>
     </TableBase>
     <ContractForm ref="ContractFormRef" @onTableList="updateOnTableList" />

+ 184 - 73
src/views/storehouse/sales/ContractDetail.vue

@@ -1,41 +1,109 @@
 <script setup lang="ts">
-import { ref } from 'vue'
+import { ref, onMounted } from 'vue'
+import { useRoute, useRouter } from 'vue-router'
 import { GlobalStore } from '@/stores/index'
-import { Storehouse_Contract_Get } from '@/api/storehouse/index'
-const info = ref({})
+import { ElMessage } from 'element-plus'
+import { Storehouse_Contract_Get, Storehouse_Contract_Approval } from '@/api/storehouse/index'
+interface InfoType {
+  Id: number
+  T_State: number
+  T_approver: string
+  T_approver_name: string
+  T_customer: string
+  T_date: string
+  T_money: number
+  T_number: string
+  T_out: number
+  T_pdf: string
+  T_remark: string
+  T_submit: string
+  T_submit_name: string
+  T_type: number
+}
+
+const info = ref<InfoType | undefined>()
 const globalStore = GlobalStore()
+const route = useRoute()
+const router = useRouter()
+const columns = [
+  { type: 'index', label: '序号', width: 80, align: 'center ' },
+  { label: '产品图片', prop: 'T_product_img', align: 'center ', name: 'T_product_img' },
+  { label: '产品名称', prop: 'T_product_name', align: 'center ' },
+  { label: '产品分类', prop: 'T_product_class_name', align: 'center ' },
+  { label: '产品型号', prop: 'T_product_model', align: 'center ', name: 'T_product_model' },
+  { label: '产品规格', prop: 'T_product_spec', align: 'center ' },
+  { label: '是否关联SN', prop: 'T_product_relation_sn', align: 'center ', width: 120, name: 'T_product_relation_sn' },
+  { label: '数量', prop: 'T_product_total', align: 'center ' },
+  { label: '已出库数量', prop: 'T_product_out', align: 'center ' },
+  { prop: 'operation', label: '操作', width: 100, fixed: 'right', align: 'center ' }
+]
+const getStorehouseContractGet = async () => {
+  const res: any = await Storehouse_Contract_Get({ User_tokey: globalStore.GET_User_tokey, T_number: route.params.id })
+  if (res.Code === 200) {
+    info.value = res.Data
+    tableData.value = res.Data.T_Product
+  }
+}
+const previewPdf = (str: string) => window.open(str)
 
-const getStorehouse_Contract_Get = async () => {
-  const res = await Storehouse_Contract_Get({ User_tokey: globalStore.GET_User_tokey, T_number: '6666666' })
-  console.log(res)
+const contractApproval = async (state: number) => {
+  const res: any = await Storehouse_Contract_Approval({
+    User_tokey: globalStore.GET_User_tokey,
+    T_number: route.params.id,
+    T_state: state
+  })
+  if (res.Code === 200) {
+    ElMessage.success('审核成功!!')
+    getStorehouseContractGet()
+  }
+}
+const getState = (val: number, type: string) => {
+  switch (val) {
+    case 1:
+      return type === 'T_State' ? '已通过' : '未出库'
+    case 2:
+      return type === 'T_State' ? '未通过' : '已部分出库'
+    case 3:
+      return type === 'T_State' ? '待审核' : '已全部出库'
+  }
 }
-getStorehouse_Contract_Get()
-const columns = []
+const tableData = ref<any[]>([])
 
-const tableData = ref([])
+onMounted(() => {
+  console.log(route.params.id)
+  getStorehouseContractGet()
+})
 </script>
 
 <template>
   <div class="contract-detail">
     <div class="info">
-      <h1>详情 - <span>待审核</span></h1>
-
+      <h1>
+        详情 - <span>{{ getState(info?.T_State!, 'T_State') }}</span>
+      </h1>
+      <el-divider />
       <div class="content">
-        <p>
-          <span>合同编号</span>
-          <span>BZD-123123123</span>
-        </p>
-        <p>
-          <span>客户名称</span>
-          <span>一树药业</span>
-        </p>
-        <p>
-          <span>合同类型</span>
-          <span>销售合同</span>
-        </p>
-        <p>
-          <span>产品明细</span>
-          <span>
+        <el-row>
+          <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="2"><span>合同编号</span></el-col>
+          <el-col :xs="11" :sm="9" :md="7" :lg="6" :xl="5"
+            ><span>{{ info?.T_number! }}</span></el-col
+          >
+        </el-row>
+        <el-row>
+          <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="2"> <span>客户名称</span></el-col>
+          <el-col :xs="11" :sm="9" :md="7" :lg="6" :xl="5"
+            ><span>{{ info?.T_customer! }}</span></el-col
+          >
+        </el-row>
+        <el-row>
+          <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="2"> <span>合同类型</span></el-col>
+          <el-col :xs="11" :sm="9" :md="7" :lg="6" :xl="5"
+            ><span>{{ info?.T_type! === 1 ? '销售合同' : '验证合同' }}</span></el-col
+          >
+        </el-row>
+        <el-row>
+          <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="2"><span>产品明细</span></el-col>
+          <el-col :span="21">
             <el-table
               :data="tableData"
               style="width: 100%"
@@ -50,63 +118,88 @@ const tableData = ref([])
               <template v-for="item in columns" :key="item.prop">
                 <el-table-column v-bind="item" v-if="item.fixed !== 'right'">
                   <template #default="{ row }" v-if="item.prop === item.name">
-                    <span v-if="item.prop === 'T_relation_sn'">
-                      <el-tag v-if="row.T_relation_sn === 1" effect="dark">是</el-tag>
+                    <span v-if="item.prop === 'T_product_relation_sn'">
+                      <el-tag v-if="row.T_product_relation_sn === 1" effect="dark">是</el-tag>
                       <el-tag v-else type="success" effect="dark">否</el-tag>
                     </span>
-                    <el-image v-if="item.prop === 'T_img'" style="height: 50px" :src="row.T_img" fit="cover" />
+                    <el-image
+                      v-if="item.prop === 'T_product_img'"
+                      style="height: 50px"
+                      :src="row.T_product_img"
+                      fit="cover"
+                    />
+                    <el-tooltip
+                      v-if="item.prop === 'T_product_model'"
+                      effect="dark"
+                      :content="row.T_product_model"
+                      placement="bottom"
+                    >
+                      {{ row.T_product_model }}
+                    </el-tooltip>
                   </template>
                 </el-table-column>
                 <el-table-column v-bind="item" v-if="item.fixed === 'right'">
-                  <el-button link type="danger" size="small">查看</el-button>
+                  <template #default="{ row }">
+                    <el-button type="primary" :disabled="!row.T_product_relation_sn">查看</el-button>
+                  </template>
                 </el-table-column>
               </template>
             </el-table>
-          </span>
-        </p>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="2"> <span>业务日期</span></el-col>
+          <el-col :xs="11" :sm="9" :md="7" :lg="6" :xl="5">
+            <span>{{ info?.T_date! }}</span></el-col
+          >
+        </el-row>
+
+        <el-row>
+          <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="2"> <span>合同金额</span></el-col>
+          <el-col :xs="11" :sm="9" :md="7" :lg="6" :xl="5">
+            <!-- <span>{{ info.T_money }}</span> -->
+            <el-text type="danger">{{ info?.T_money! }}</el-text>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <!-- 1-未出库 2-已部分出库 3-已全部出库 -->
+          <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="2"><span>出库状态</span></el-col>
+          <el-col :xs="11" :sm="9" :md="7" :lg="6" :xl="5"
+            ><span>{{ getState(info?.T_out!, 'T_out') }}</span></el-col
+          >
+        </el-row>
+
+        <el-row>
+          <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="2"><span>经办人</span></el-col>
+          <el-col :xs="11" :sm="9" :md="7" :lg="6" :xl="5"
+            ><span>{{ info?.T_submit_name! }}</span></el-col
+          >
+        </el-row>
+
+        <el-row>
+          <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="2"><span>合同备注</span></el-col>
+          <el-col :xs="11" :sm="9" :md="7" :lg="6" :xl="5"
+            ><span>{{ info?.T_remark! }}</span></el-col
+          >
+        </el-row>
+
+        <el-row>
+          <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="2"><span>附件</span></el-col>
+          <el-col :xs="11" :sm="9" :md="7" :lg="6" :xl="5"
+            ><span v-if="!info?.T_pdf!">无</span>
+            <el-button v-else type="primary" @click="previewPdf(info?.T_pdf!)">查看附件</el-button></el-col
+          >
+        </el-row>
+      </div>
+
+      <el-divider />
+      <div class="submit">
+        <el-button v-if="info?.T_State === 3" type="danger" round @click="contractApproval(2)">审核不通过</el-button>
+        <el-button v-if="info?.T_State === 3" type="success" round @click="contractApproval(1)">审核通过</el-button>
+        <el-button type="primary" round @click="router.back()">返回</el-button>
       </div>
     </div>
-    <!-- <el-table
-            :data="tableData"
-            style="width: 100%"
-            border
-            stripe
-            :header-cell-style="{
-              background: '#909399',
-              height: '50px',
-              color: '#fff'
-            }"
-          >
-            <template v-for="item in columns" :key="item.prop">
-              <el-table-column v-bind="item" v-if="item.fixed !== 'right'">
-                <template #header v-if="item.prop === 'count'">
-                  <span style="color: red">*数量</span>
-                </template>
-                <template #default="{ row }" v-if="item.prop === item.name">
-                  <el-input
-                    v-if="item.prop === 'count'"
-                    v-model.number="row.count"
-                    type="text"
-                    autocomplete="off"
-                    @blur="blurHandle"
-                  />
-                  <span v-if="item.prop === 'T_relation_sn'">
-                    <el-tag v-if="row.T_relation_sn === 1" effect="dark">是</el-tag>
-                    <el-tag v-else type="success" effect="dark">否</el-tag>
-                  </span>
-                  <el-image v-if="item.prop === 'T_img'" style="height: 50px" :src="row.T_img" fit="cover" />
-                </template>
-              </el-table-column>
-              <el-table-column v-bind="item" v-if="item.fixed === 'right'">
-                <el-button link type="danger" size="small" :icon="Delete">删除</el-button>
-              </el-table-column>
-            </template>
-            <template #append>
-              <el-button type="primary" @click="AddProductionDetailed">
-                <el-icon><Plus /></el-icon><span style="margin-left: 6px">添加产品</span>
-              </el-button>
-            </template>
-          </el-table> -->
   </div>
 </template>
 
@@ -116,7 +209,25 @@ const tableData = ref([])
   font-weight: bold;
   color: var(--el-text-color-secondary);
   .info {
+    height: 100%;
     padding: 20px;
+    h1 {
+      font-size: 24px;
+      span {
+        color: #f56c6c;
+      }
+    }
+    & .content {
+      height: calc(100% - 72px - 25px - 40px);
+      overflow-y: scroll;
+      .el-row {
+        margin-bottom: 16px;
+      }
+    }
+    .submit {
+      display: flex;
+      justify-content: center;
+    }
   }
 }
 </style>

+ 88 - 43
src/views/storehouse/sales/ContractForm.vue

@@ -3,24 +3,22 @@ import { ref, reactive, nextTick } from 'vue'
 import Drawer from '@/components/Drawer/index.vue'
 import Dialog from '@/components/dialog/Dialog.vue'
 import type { FormInstance, FormRules } from 'element-plus'
-// import type { TableColumnCtx } from 'element-plus'
 import { Delete } from '@element-plus/icons-vue'
 import { GlobalStore } from '@/stores/index'
-import TableBase from '@/components/TableBase/index.vue'
 import Upload from '@/components/Upload/index.vue'
 import {
   Storehouse_Contract_Add,
   Storehouse_Product_List,
-  Storehouse_IotCard_Edit,
+  Storehouse_Contract_Edit,
   Storehouse_ProductClass_List,
   Storehouse_Product_Model_List,
-  Storehouse_Product_Name_List
+  Storehouse_Product_Name_List,
+  Storehouse_Contract_Product_List
 } from '@/api/storehouse/index'
-import { debounce } from '@/utils/common'
-import { ElMessageBox, ElMessage } from 'element-plus'
+import { ElMessage } from 'element-plus'
 import { default as vElTableInfiniteScroll } from 'el-table-infinite-scroll'
-import { log } from 'console'
 
+let selectProductData: any[] = []
 const isNew = ref(true)
 const globalStore = GlobalStore()
 const formLabelWidth = ref('120px')
@@ -52,12 +50,14 @@ const rules = reactive<FormRules>({
 
 const callbackDrawer = (done: Fn) => {
   resetForm(ruleFormRef.value)
+  isNew.value = true
   done()
 }
 const callbackProductDrawer = (done: Fn) => done()
 
 const resetForm = (formEl: FormInstance | undefined) => {
   if (!formEl) return
+  tableData.value = []
   formEl.resetFields()
 }
 
@@ -66,7 +66,7 @@ const emit = defineEmits<{ (event: 'onTableList'): void }>()
 
 // 添加仓库名称
 interface FormType {
-  T_id: string
+  // T_id: string
   T_number: string
   T_customer: string
   T_type: any
@@ -78,7 +78,7 @@ interface FormType {
 }
 type Fn = () => void
 const form = reactive<FormType>({
-  T_id: '',
+  // T_id: '',
   T_number: '',
   T_customer: '',
   T_type: '',
@@ -90,17 +90,46 @@ const form = reactive<FormType>({
 })
 
 const openDrawer = (type: string, row?: any) => {
-  console.log(type, row)
   isNew.value = type === 'new' ? true : false
-  // nextTick(() => {
-  //   form.T_id = row.Id
-  //   form.T_sn = row.T_sn
-  //   form.T_type = row.T_type
-  //   form.T_state = row.T_State
-  //   form.T_iccid = row.T_iccid
-  // })
+  if (!isNew.value) {
+    nextTick(() => {
+      editDataEcho(row)
+    })
+  }
   drawerRef.value?.openDrawer()
 }
+// edit data echo
+const editDataEcho = async (row: any) => {
+  // console.log(row)
+  // form.T_id = row.Id
+  form.T_pdf = row.T_pdf
+  form.T_date = row.T_date
+  form.T_type = row.T_type
+  form.T_money = row.T_money
+  form.T_remark = row.T_remark
+  form.T_number = row.T_number
+  form.T_customer = row.T_customer
+
+  const res: any = await Storehouse_Contract_Product_List({
+    User_tokey: globalStore.GET_User_tokey,
+    T_number: row.T_number
+  })
+  if (res.Code === 200) {
+    res.Data &&
+      (tableData.value = res.Data.map((item: any) => {
+        item.Id = item.T_product_id
+        item.T_img = item.T_product_img
+        item.T_name = item.T_product_name
+        item.T_class_name = item.T_product_class_name
+        item.T_model = item.T_product_model
+        item.T_spec = item.T_product_spec
+        item.T_relation_sn = item.T_product_relation_sn
+        item.count = item.T_product_total
+        return item
+      }))
+    selectProductData = tableData.value
+  }
+}
 
 const blurHandle = () => {
   form.T_product = tableData.value.map(item => {
@@ -108,34 +137,33 @@ const blurHandle = () => {
     return `${item.Id},${item.count}`
   })
 }
-const deleteProduct = (id: number) => {
-  tableData.value = tableData.value.filter(item => item.Id !== id)
-  console.log(id)
+const deleteProduct = (row: any) => {
+  tableData.value = tableData.value.filter(item => item.Id !== row.Id)
 
-  selectTable.value?.toggleRowSelection([tableData.value[1]])
+  // 设置产品的选中
+  selectTable.value?.toggleRowSelection(row, false)
 }
 
 const AddContract = (formEl: FormInstance | undefined) => {
   if (!formEl) return
-  // form.T_product = tableData.value.map(item => {
-  //   if (!item.count) return undefined
-  //   return `${item.Id},${item.count}`
-  // })
-
   formEl.validate(async valid => {
     if (valid) {
       let res: any = {}
+      let product = ''
+      tableData.value.forEach(item => {
+        product += `${item.Id},${item.count}|`
+      })
       if (isNew.value) {
-        console.log(form)
         res = await Storehouse_Contract_Add({
           ...form,
           User_tokey: globalStore.GET_User_tokey,
-          T_product: form.T_product.toString()
+          T_product: product
         })
       } else {
-        res = await Storehouse_IotCard_Edit({
-          User_tokey: globalStore.GET_User_tokey,
-          ...form
+        res = await Storehouse_Contract_Edit({
+          ...form,
+          T_product: product,
+          User_tokey: globalStore.GET_User_tokey
         })
       }
       if (res.Code === 200) {
@@ -199,7 +227,14 @@ const getRowKey = (row: any) => {
 }
 // 选中的产品
 const ProductselectionChange = (row: any[]) => {
-  tableData.value = row
+  if (!isNew.value) {
+    const newProduct = row.find(
+      (product: any) => tableData.value.findIndex((item: any) => item.Id === product.Id) === -1
+    )
+    newProduct && tableData.value.push({ ...newProduct })
+  } else {
+    tableData.value = row
+  }
 }
 
 // 加载第二个抽屉数据
@@ -215,9 +250,16 @@ let total = 0
 const tableProductData = ref<any[]>([])
 const getProductList = async () => {
   const res: any = await Storehouse_Product_List({ ...initParam, T_name: autoSelect.value })
-  console.log(res)
   tableProductData.value.push(...res.Data.Data)
   total = res.Data.Num
+  if (!isNew.value) {
+    // 设置产品的选中
+    tableProductData.value.forEach((row: any) => {
+      const matchedIndex = selectProductData.findIndex((item: any) => item.Id == row.Id)
+
+      selectTable.value?.toggleRowSelection(row, matchedIndex != -1)
+    })
+  }
 }
 
 const tableData = ref<any[]>([])
@@ -230,7 +272,6 @@ const columns = [
   { label: '产品规格', prop: 'T_spec', align: 'center ' },
   { label: '是否关联SN', prop: 'T_relation_sn', align: 'center ', width: 120, name: 'T_relation_sn' },
   { label: '*数量', prop: 'count', align: 'center ', name: 'count' },
-  { label: '备注', prop: 'T_remark', align: 'center ' },
   { prop: 'operation', label: '操作', width: 80, fixed: 'right' }
 ]
 
@@ -291,16 +332,23 @@ defineExpose({
           <el-input
             v-model="form.T_number"
             type="text"
+            :disabled="!isNew"
             autocomplete="off"
-            placeholder="请输入物联网卡号"
+            placeholder="请输入合同编号"
             class="w-50"
           />
         </el-form-item>
         <el-form-item label="客户名称:" :label-width="formLabelWidth" prop="T_customer">
-          <el-input v-model="form.T_customer" type="text" autocomplete="off" placeholder="请输入型号" class="w-50" />
+          <el-input
+            v-model="form.T_customer"
+            type="text"
+            autocomplete="off"
+            placeholder="请输入客户名称"
+            class="w-50"
+          />
         </el-form-item>
         <el-form-item label="合同类型:" :label-width="formLabelWidth" prop="T_type">
-          <el-select v-model="form.T_type" class="w-50" clearable placeholder="请选择~">
+          <el-select v-model="form.T_type" class="w-50" clearable :disabled="!isNew" placeholder="请选择合同类型~">
             <el-option label="销售合同" :value="1" />
             <el-option label="验证合同" :value="2" />
           </el-select>
@@ -339,9 +387,7 @@ defineExpose({
               </el-table-column>
               <el-table-column v-bind="item" v-if="item.fixed === 'right'">
                 <template #default="{ row }">
-                  <el-button link type="danger" size="small" :icon="Delete" @click="deleteProduct(row.Id)"
-                    >删除</el-button
-                  >
+                  <el-button link type="danger" size="small" :icon="Delete" @click="deleteProduct(row)">删除</el-button>
                 </template>
               </el-table-column>
             </template>
@@ -395,14 +441,14 @@ defineExpose({
           <el-divider>
             <el-button>取消</el-button>
             <el-button v-if="isNew" color="#626aef" @click="AddContract(ruleFormRef)">提交</el-button>
-            <el-button v-else color="#626aef">修改</el-button>
+            <el-button v-else color="#626aef" @click="AddContract(ruleFormRef)">修改</el-button>
           </el-divider>
         </div>
         <Drawer ref="drawerProductRef" :handleClose="callbackProductDrawer" size="70%">
           <template #header="{ params }">
             <h4 :id="params.titleId" :class="params.titleClass">选择产品</h4>
           </template>
-          <el-card class="box-card">
+          <el-card class="box-card" shadow="never">
             <template #header>
               <div class="input-suffix">
                 <el-row :gutter="20" style="margin-bottom: 0">
@@ -441,7 +487,6 @@ defineExpose({
             </template>
             <el-table
               ref="selectTable"
-              border
               :row-key="getRowKey"
               :data="tableProductData"
               style="width: 100%; height: 99%"

+ 149 - 0
src/views/storehouse/sales/ContractSale.vue

@@ -0,0 +1,149 @@
+<script setup lang="ts">
+import { GlobalStore } from '@/stores/index'
+import { ref, reactive, nextTick } from 'vue'
+import ContractForm from './ContractForm.vue'
+import { useRouter } from 'vue-router'
+import { ElMessageBox, ElMessage } from 'element-plus'
+import TableBase from '@/components/TableBase/index.vue'
+import { Edit, Delete, Finished, View } from '@element-plus/icons-vue'
+import type { ColumnProps } from '@/components/TableBase/interface/index'
+import {
+  Storehouse_Contract_List,
+  Storehouse_Contract_Del,
+  Storehouse_Contract_User_List
+} from '@/api/storehouse/index'
+
+const router = useRouter()
+const globalStore = GlobalStore()
+const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
+const ContractFormRef = ref<InstanceType<typeof ContractForm> | null>(null)
+
+const columns: ColumnProps[] = [
+  { type: 'index', label: '序号', width: 80 },
+  { prop: 'T_number', label: '合同编号' },
+  { prop: 'T_customer', label: '客户名称' },
+  { prop: 'T_State', label: '状态', name: 'T_State' },
+  { prop: 'T_out', label: '是否出库', name: 'T_out' },
+  { prop: 'T_date', label: '更新时间' },
+  { prop: 'operation', label: '操作', width: 260, fixed: 'right' }
+]
+
+const openContractFormDrawer = (type: string, row?: any) => {
+  ContractFormRef.value?.openDrawer(type, row)
+}
+
+const updateOnTableList = () => TableRef.value?.getTableList()
+// 审核
+const processContract = (id: string) => {
+  router.push({ name: 'ContractDetail', params: { id } })
+}
+// 删除
+const UserDelete = (row: any) => {
+  ElMessageBox.confirm('您确定要删除该销售合同吗?', '警告', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning'
+  })
+    .then(async () => {
+      const res: any = await Storehouse_Contract_Del({ User_tokey: globalStore.GET_User_tokey, T_number: row.T_number })
+      if (res.Code === 200) {
+        ElMessage.success('删除成功!')
+        nextTick(() => {
+          TableRef.value?.getTableList()
+        })
+      }
+    })
+    .catch(() => {
+      ElMessage.warning('取消成功!')
+    })
+}
+
+// 搜索
+const options = reactive([
+  { name: '已通过', id: 1 },
+  { name: '未通过', id: 2 },
+  { name: '待审核', id: 3 }
+])
+const initParam = reactive({
+  User_tokey: globalStore.GET_User_tokey,
+  T_name: '',
+  T_state: ''
+})
+const searchHandle = () => {
+  TableRef.value?.searchTable()
+}
+</script>
+
+<template>
+  <div class="contract">
+    <TableBase ref="TableRef" :columns="columns" :requestApi="Storehouse_Contract_User_List" :initParam="initParam">
+      <template #table-header>
+        <div class="input-suffix">
+          <el-row :gutter="20" style="margin-bottom: 0">
+            <el-col :xl="6" :lg="8" :md="10">
+              <span class="inline-flex items-center">合同编号:</span>
+              <el-input
+                v-model="initParam.T_name"
+                type="text"
+                class="w-50 m-2"
+                placeholder="按产品名称搜索"
+                @change="searchHandle"
+              />
+            </el-col>
+            <el-col :xl="10" :md="12">
+              <span class="inline-flex items-center">状态:</span>
+              <el-select v-model="initParam.T_state" class="w-50" clearable placeholder="请选择状态~">
+                <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+              <el-button type="primary" @click="searchHandle">搜索</el-button>
+            </el-col>
+            <el-col :xl="6" :md="2" class="btn"
+              ><el-button type="primary" @click="openContractFormDrawer('new')">添加</el-button></el-col
+            >
+          </el-row>
+        </div>
+      </template>
+      <template #T_State="{ row }">
+        <el-tag v-if="row.T_State === 1" type="success" effect="dark"> 已通过 </el-tag>
+        <el-tag v-else-if="row.T_State === 2" type="warning" effect="dark"> 未通过 </el-tag>
+        <el-tag v-else type="danger" effect="dark"> 待审核 </el-tag>
+      </template>
+      <template #T_out="{ row }">
+        <el-tag v-if="row.T_out === 2 || row.T_out === 3" type="success" effect="dark">
+          {{ row.T_out === 2 ? '已出库' : '已全部出库' }}
+        </el-tag>
+        <el-tag v-else-if="row.T_State === 1" type="warning" effect="dark"> 未出库 </el-tag>
+        <el-tag v-else type="danger" effect="dark"> --- </el-tag>
+      </template>
+      <template #right="{ row }">
+        <el-button link type="primary" size="small" :icon="Edit" @click="openContractFormDrawer('edit', row)"
+          >编辑</el-button
+        >
+        <el-button link type="success" size="small" :icon="View" @click="processContract(row.T_number)">详情</el-button>
+        <el-button link type="danger" size="small" :icon="Delete" @click="UserDelete(row)">删除</el-button>
+      </template>
+    </TableBase>
+    <ContractForm ref="ContractFormRef" @onTableList="updateOnTableList" />
+  </div>
+</template>
+
+<style scoped lang="scss">
+.contract {
+  :deep(.el-drawer__header) {
+    margin-bottom: 0;
+  }
+  .input-suffix {
+    width: 100%;
+    .inline-flex {
+      white-space: nowrap;
+    }
+    .btn {
+      display: flex;
+      justify-content: end;
+    }
+    .w-50 {
+      width: 12.5rem;
+    }
+  }
+}
+</style>