浏览代码

feat: ✨ 完成设备管理、合同管理

@sun-chaoqun 2 年之前
父节点
当前提交
a8bd102e69

+ 2 - 0
README.md

@@ -33,3 +33,5 @@ https://6b87x3.axshare.com/#id=s9uw1m&p=%E6%88%91%E7%9A%84%E5%8A%A0%E7%8F%AD&g=1
 销售合同(销售): 通过后屏蔽掉编辑、删除
 
 合同详情:查看 SN 未做
+
+合同详情,等动态路由做完还要测试一下

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

@@ -74,3 +74,31 @@ export const Storehouse_Contract_Del = (params: any) => $http.post('/testapi/sto
 // 产品列表
 export const Storehouse_Contract_Product_List = (params: any) =>
   $http.post('/testapi/storage/Contract/Product_List', params)
+
+/**
+ * 库存管理
+ */
+// 设备列表
+export const Storehouse_Device_List = (params: any) => $http.post('/testapi/storage/Device/List', params)
+
+/**
+ * 入库
+ */
+// 入库列表
+export const Storehouse_StockIn_List = (params: any) => $http.post('/testapi/storage/StockIn/List', params)
+// 详情
+export const Storehouse_StockIn_Get = (params: any) => $http.post('/testapi/storage/StockIn/Get', params)
+// 入库
+export const Storehouse_StockIn_Add = (params: any) => $http.post('/testapi/storage/StockIn/Add', params)
+
+/**
+ * 出库
+ */
+// 出库列表
+export const Storehouse_StockOut_List = (params: any) => $http.post('/testapi/storage/StockOut/List', params)
+// 出库
+export const Storehouse_StockOut_Add = (params: any) => $http.post('/testapi/storage/StockOut/Add', params)
+// 详情
+export const Storehouse_StockOut_Get = (params: any) => $http.post('/testapi/storage/StockOut/Get', params)
+// 修改发货订单
+export const Storehouse_StockOut_Edit = (params: any) => $http.post('/testapi/storage/StockOut/Edit', params)

+ 3 - 1
src/components/TableBase/index.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { ref, onMounted, onUnmounted } from 'vue'
+import { ref, onMounted, onUnmounted, CSSProperties } from 'vue'
 import Pagination from './components/Pagination.vue'
 import { useTable } from '@/hooks/useTable'
 import { ElTable, TableProps } from 'element-plus'
@@ -21,6 +21,7 @@ interface ProTableProps extends Partial<Omit<TableProps<any>, 'data'>> {
   rowClick?: (row: any, column: any, event: any) => void // 点击行
   selectionChange?: (row: any) => void // 选择函数
   getRowKey?: ((row: any) => string) | string // 用于优化select勾选框
+  tableRowClassName?: (data: any) => CSSProperties
 }
 
 // 接受父组件参数,配置默认值
@@ -83,6 +84,7 @@ defineExpose({
       @selection-change="props.selectionChange"
       :border="border"
       :row-key="props.getRowKey"
+      :row-style="tableRowClassName"
     >
       <!-- 默认插槽 -->
       <slot></slot>

+ 31 - 6
src/hooks/useTable.ts

@@ -1,4 +1,4 @@
-import { reactive, toRefs } from 'vue'
+import { reactive, toRefs, watch } from 'vue'
 interface Pageable {
   pageNum: number
   pageSize: number
@@ -26,8 +26,9 @@ interface Table {
 export const useTable = (
   requestApi: (params: any) => Promise<any>,
   initParam: object = {},
-  isPagination: boolean = true,
-  dataCallback?: (data: any) => any
+  isPagination?: boolean = true,
+  dataCallback?: (data: any) => any,
+  uuid?: string
 ) => {
   const state = reactive<Table>({
     // 表格数据
@@ -67,9 +68,6 @@ export const useTable = (
     }
   }
 
-  if (isPagination) {
-  }
-
   const handleSizeChange = (val: number) => {
     state.pageable.pageSize = val
     getTableList()
@@ -85,11 +83,38 @@ export const useTable = (
     getTableList()
   }
 
+  // watch(
+  //   () => uuid,
+  //   pre => {
+  //     console.log(pre)
+  //   }
+  // )
+
+  // const tableRowClassName = ({ row, rowIndex }) => {
+  //   console.log(uuid)
+  //   //判断是否相等,相同时改变背景颜色
+  //   // let user = this.multipleSelection.find(item => item.autoid === row.autoid)
+  //   let rowBackground = {
+  //     background: '#95d475'
+  //   }
+  //   return rowBackground
+  //   // if (list !== undefined) {
+  //   //   let rowBackground = {
+  //   //     background: '#9FBBFF'
+  //   //   }
+  //   //   //rowBackground.color = "red" //字体颜色
+  //   //   return rowBackground
+  //   // } else {
+  //   //   return ''
+  //   // }
+  // }
+
   return {
     ...toRefs(state),
     getTableList,
     searchTable,
     handleSizeChange,
     handleCurrentChange
+    // tableRowClassName
   }
 }

+ 10 - 1
src/layouts/Header/Breadcrumb.vue

@@ -12,7 +12,7 @@ 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)
@@ -58,6 +58,15 @@ const onBreadcrumbClick = (item: any, index: number) => {
     width: 16px;
     color: #fff;
   }
+  .cursor.el-breadcrumb__item {
+    cursor: auto;
+    .el-breadcrumb__inner {
+      cursor: auto;
+      .breadcrumb-title {
+        cursor: auto;
+      }
+    }
+  }
   .el-breadcrumb {
     white-space: nowrap;
     .el-breadcrumb__item {

+ 59 - 3
src/layouts/Header/Notice.vue

@@ -1,6 +1,62 @@
-<script setup lang="ts"></script>
+<script setup lang="ts">
+import { ref } from 'vue'
+import type { TabsPaneContext } from 'element-plus'
+const activeName = ref('first')
+
+const handleClick = (tab: TabsPaneContext, event: Event) => {
+  console.log(tab, event)
+}
+</script>
 <template>
-  <div class="notice"></div>
+  <div class="notice">
+    <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+      <el-tab-pane label="未读" name="first">
+        <div class="list">
+          <p class="scrollbar-item">
+            <el-badge is-dot class="item">query</el-badge>
+          </p>
+          <p class="scrollbar-item">
+            <el-badge is-dot class="item">query</el-badge>
+          </p>
+          <p class="scrollbar-item">
+            <el-badge is-dot class="item">query</el-badge>
+          </p>
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="全部" name="second">
+        <div class="list">
+          <p class="scrollbar-item">
+            <el-badge is-dot class="item">query</el-badge>
+          </p>
+          <p class="scrollbar-item">
+            <el-badge is-dot class="item">query</el-badge>
+          </p>
+          <p class="scrollbar-item">
+            <el-badge is-dot class="item">query</el-badge>
+          </p>
+        </div>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
 </template>
 
-<style scoped></style>
+<style scoped lang="scss">
+.notice {
+  .list {
+    display: flex;
+    flex-direction: column;
+    .scrollbar-item {
+      font-size: 16px;
+      display: flex;
+      align-items: center;
+      justify-content: start;
+      // height: 50px;
+      margin: 10px;
+      text-align: center;
+      border-radius: 4px;
+      // background: var(--el-color-primary-light-9);
+      // color: var(--el-color-primary);
+    }
+  }
+}
+</style>

+ 10 - 2
src/layouts/Header/index.vue

@@ -3,6 +3,7 @@ import { ref } from 'vue'
 import { useRouter } from 'vue-router'
 import { GlobalStore } from '@/stores/index'
 import Breadcrumb from './Breadcrumb.vue'
+import Notice from './Notice.vue'
 import { Expand, Fold } from '@element-plus/icons-vue'
 import 'element-plus/theme-chalk/src/dropdown.scss'
 const globalStore = GlobalStore()
@@ -44,14 +45,21 @@ setInterval(() => {
         <Breadcrumb></Breadcrumb>
       </el-col>
       <el-col :xl="2" :sm="2" class="notice">
+        <!-- <el-popover placement="bottom-end" :width="400" trigger="click">
+          <template #reference>
+            <el-button type="primary" circle>
+              <i class="iconfont el-icon">&#xe63e;</i>
+            </el-button>
+          </template>
+          <Notice></Notice>
+        </el-popover> -->
         <el-dropdown>
-          <!-- <el-icon :size="25"><Bell /></el-icon> -->
           <el-button type="primary" circle>
             <i class="iconfont el-icon">&#xe63e;</i>
           </el-button>
           <template #dropdown>
             <el-dropdown-menu>
-              <el-dropdown-item>Action 2</el-dropdown-item>
+              <el-dropdown-item>action</el-dropdown-item>
             </el-dropdown-menu>
           </template>
         </el-dropdown>

+ 1 - 1
src/router/index.ts

@@ -19,7 +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)
+    // console.log(to.path)
     if (!store.GET_Flat_Menu.length) {
       await initDynamicRouter()
       return next({ ...to, replace: true })

+ 28 - 0
src/router/modules/staticRouter.ts

@@ -81,6 +81,34 @@ export const staticRouter: RouteRecordRaw[] = [
           }
         ]
       },
+      {
+        path: '/inventoryMange',
+        name: 'InventoryMange',
+        component: () => import('@/views/storehouse/inventory/index.vue'),
+        // redirect: '/contract',
+        meta: {
+          routerView: true,
+          title: '库存管理'
+        },
+        children: [
+          {
+            path: '/device',
+            name: 'Device',
+            component: () => import('@/views/storehouse/inventory/Device.vue'),
+            meta: {
+              title: '设备列表'
+            }
+          },
+          {
+            path: '/inStorage',
+            name: 'InStorage',
+            component: () => import('@/views/storehouse/inventory/InStorage.vue'),
+            meta: {
+              title: '入库管理'
+            }
+          }
+        ]
+      },
       // {
       //   path: '/contract',
       //   name: 'Contract',

+ 21 - 4
src/views/salary/salary/Salary.vue

@@ -22,7 +22,7 @@ const salaryFromRef = ref<InstanceType<typeof SalaryFrom> | null>(null)
 
 // 搜索以及参数
 const columns: ColumnProps[] = [
-  { prop: 'T_name', label: '姓名', name: 'T_name' },
+  { prop: 'T_name', label: '姓名' },
   { prop: 'T_post_name', label: '职位' }
 ]
 
@@ -80,6 +80,22 @@ const onResize = () => {
   const table_header = document.querySelector('.table-header') as HTMLDivElement
   return height - table_header.clientHeight - 24 - 60 - 12
 }
+
+const tableRowClassName = (data: any): any => {
+  //判断是否相等,相同时改变背景颜色
+  let user: any = undefined
+  if (data.row.T_uuid === salaryFromData.T_uuid) {
+    user = data.row
+  }
+  if (user !== undefined) {
+    let rowBackground = {
+      background: '#95d475'
+    }
+    return rowBackground
+  } else {
+    return ''
+  }
+}
 </script>
 
 <template>
@@ -93,6 +109,7 @@ const onResize = () => {
         layout="prev, pager, next"
         :onResize="onResize"
         :rowClick="getSalaryParams"
+        :tableRowClassName="tableRowClassName"
       >
         <template #table-header>
           <el-row :gutter="24" class="input-suffix margin-left-0 margin-right-0">
@@ -114,9 +131,9 @@ const onResize = () => {
             </el-col>
           </el-row>
         </template>
-        <template #T_name="{ row }">
+        <!-- <template #T_name="{ row }">
           <el-button type="primary" text @click="getSalaryParams(row)">{{ row.T_name }}</el-button>
-        </template>
+        </template> -->
       </TableBase>
     </div>
     <el-row class="h-100 f-1 margin-left-3">
@@ -136,7 +153,7 @@ const onResize = () => {
         </el-card>
         <el-card class="m-b-3">
           <el-row :gutter="20">
-            <el-col :span="10" class="d-flex justify-start">
+            <el-col :xl="10" :lg="12" :md="14" class="d-flex justify-start">
               <span class="demonstration">年:</span>
               <el-date-picker
                 v-model="salaryFromData.year"

+ 10 - 6
src/views/salary/salary/SalaryFrom.vue

@@ -1,6 +1,6 @@
 <script setup lang="ts">
 import { reuls_validator } from './relus'
-import { ElNotification } from 'element-plus'
+import { ElNotification, ElMessage } from 'element-plus'
 import { Salary_Post } from '@/api/salary/index'
 import { ref, reactive, onMounted, onUnmounted } from 'vue'
 import type { FormInstance, FormRules } from 'element-plus'
@@ -28,13 +28,17 @@ const resetForm = (formEl: FormInstance | undefined) => {
   if (!formEl) return
   formEl.resetFields()
 }
-const formLabelWidth = ref('9.5rem')
+const formLabelWidth = ref('10rem')
 const submitSalary = (formEl: FormInstance | undefined) => {
   if (!formEl) return
+  if (!props.T_uuid) {
+    ElMessage.warning('请选择员工!!!')
+    return
+  }
   formEl.validate(async valid => {
     if (valid) {
       const T_date = props.year + '-' + props.month
-      const res: any = await Salary_Post({ T_uuid: props.T_uuid, T_date, ...form.value })
+      const res: any = await Salary_Post({ ...form.value, T_uuid: props.T_uuid, T_date })
       if (res.Code === 200) {
         ElNotification({
           title: '提交成功',
@@ -91,10 +95,10 @@ onUnmounted(() => {
           <el-form-item label="工龄工资:" :label-width="formLabelWidth" prop="T_seniority">
             <el-input v-model="form.T_seniority" autocomplete="off" placeholder="¥" />
           </el-form-item>
-          <el-form-item label="绩效金额:" :label-width="formLabelWidth" prop="T_Perf">
+          <el-form-item label="绩效金额:" :label-width="formLabelWidth" prop="T_perf">
             <el-input v-model="form.T_perf" autocomplete="off" placeholder="¥" />
           </el-form-item>
-          <el-form-item label="绩效得分:" :label-width="formLabelWidth" prop="T_Perf_score">
+          <el-form-item label="绩效得分:" :label-width="formLabelWidth" prop="T_perf_score">
             <el-input v-model="form.T_perf_score" autocomplete="off" placeholder="¥" />
           </el-form-item>
           <el-form-item label="其他补款:" :label-width="formLabelWidth" prop="T_back_payment">
@@ -120,7 +124,7 @@ onUnmounted(() => {
           <el-form-item label="需缴住房公积金:" :label-width="formLabelWidth" prop="T_medical_insurance">
             <el-input v-model="form.T_medical_insurance" autocomplete="off" placeholder="¥" />
           </el-form-item>
-          <el-form-item label="需缴纳失业保险:" :label-width="formLabelWidth" prop="T_Large_medical_insurance">
+          <el-form-item label="需缴纳失业保险:" :label-width="formLabelWidth" prop="T_large_medical_insurance">
             <el-input v-model="form.T_large_medical_insurance" autocomplete="off" placeholder="¥" />
           </el-form-item>
           <el-form-item label="需缴大额医疗保险:" :label-width="formLabelWidth" prop="T_housing_fund">

+ 23 - 21
src/views/salary/salary/relus.ts

@@ -2,31 +2,33 @@ import type { FormRules } from 'element-plus'
 
 export const floatReg = /^[-\+]?\d+(\.\d+)?$/
 
-const validate_float = (rule: any, value: any, callback: any) => {
-  if (value === '') {
-    callback(new Error('请输入金额'))
-  } else {
-    if (floatReg.test(value) || /\d+/.test(value)) {
-      callback()
+const validate_float = () => {
+  return (rule: any, value: any, callback: any) => {
+    if (value === '') {
+      callback(new Error('请输入金额'))
     } else {
-      callback(new Error('金额必须是数字或小数'))
+      if (floatReg.test(value) || /\d+/.test(value)) {
+        callback()
+      } else {
+        callback(new Error('金额必须是数字或小数'))
+      }
     }
   }
 }
 
 export const reuls_validator: FormRules = {
-  T_base: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_post: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_seniority: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_Perf: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_Perf_score: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_back_payment: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_tax: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_attendance: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_cut_payment: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_pension_insurance: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_unemployment_insurance: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_medical_insurance: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_Large_medical_insurance: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_housing_fund: [{ required: true, validator: validate_float, trigger: 'blur' }]
+  T_base: [{ required: true, validator: validate_float(), trigger: 'blur' }],
+  T_post: [{ required: true, validator: validate_float(), trigger: 'blur' }],
+  T_seniority: [{ required: true, validator: validate_float(), trigger: 'blur' }],
+  T_perf: [{ required: true, validator: validate_float(), trigger: 'blur' }],
+  T_perf_score: [{ required: true, validator: validate_float(), trigger: 'blur' }],
+  T_back_payment: [{ required: true, validator: validate_float(), trigger: 'blur' }],
+  T_tax: [{ required: true, validator: validate_float(), trigger: 'blur' }],
+  T_attendance: [{ required: true, validator: validate_float(), trigger: 'blur' }],
+  T_cut_payment: [{ required: true, validator: validate_float(), trigger: 'blur' }],
+  T_pension_insurance: [{ required: true, validator: validate_float(), trigger: 'blur' }],
+  T_unemployment_insurance: [{ required: true, validator: validate_float(), trigger: 'blur' }],
+  T_medical_insurance: [{ required: true, validator: validate_float(), trigger: 'blur' }],
+  T_large_medical_insurance: [{ required: true, validator: validate_float(), trigger: 'blur' }],
+  T_housing_fund: [{ required: true, validator: validate_float(), trigger: 'blur' }]
 }

+ 110 - 0
src/views/storehouse/inventory/Device.vue

@@ -0,0 +1,110 @@
+<script setup lang="ts">
+import { ref, reactive } from 'vue'
+import { GlobalStore } from '@/stores/index'
+import Dialog from '@/components/dialog/Dialog.vue'
+import TableBase from '@/components/TableBase/index.vue'
+import type { ColumnProps } from '@/components/TableBase/interface/index'
+import { Storehouse_Device_List } from '@/api/storehouse/index'
+
+const globalStore = GlobalStore()
+const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
+
+const columns: ColumnProps[] = [
+  { type: 'index', label: '序号', width: 80 },
+  { prop: 'T_contract_number', label: '合同编号', ellipsis: true },
+  { prop: 'T_out_number', label: '出库单号', ellipsis: true },
+  { prop: 'T_product_img', label: '产品图片', name: 'T_product_img' },
+  { prop: 'T_product_name', label: '产品名称' },
+  { prop: 'T_product_class_name', label: '产品分类' },
+  { prop: 'T_product_model', label: '产品型号', ellipsis: true },
+  { prop: 'T_product_spec', label: '产品规格' },
+  { prop: 'T_sn', label: '设备SN', ellipsis: true },
+  { prop: 'T_imei', label: '模组imei', ellipsis: true },
+  { prop: 'T_iccid', label: '物联网卡号', ellipsis: true },
+  { prop: 'T_State', label: '状态', name: 'T_State' }
+]
+
+// 查看图片
+const url = ref('')
+const srcList = ref<any[]>([])
+const dialog = ref<InstanceType<typeof Dialog> | null>(null)
+const previewImg = (str: string) => {
+  dialog.value?.DialogOpen()
+  url.value = str
+  srcList.value.push(str)
+}
+
+// 搜索
+const options = reactive([
+  { name: '已出库', id: 1 },
+  { name: '未出库', id: 2 }
+])
+const initParam = reactive({
+  User_tokey: globalStore.GET_User_tokey,
+  T_name: '',
+  T_state: ''
+})
+const searchHandle = () => {
+  TableRef.value?.searchTable()
+}
+</script>
+
+<template>
+  <div class="Device">
+    <TableBase ref="TableRef" :columns="columns" :requestApi="Storehouse_Device_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="按合同编号、出库单号、SN搜索"
+                @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-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 type="danger" effect="dark"> 未出库 </el-tag>
+      </template>
+      <template #T_product_img="{ row }">
+        <el-image
+          v-if="row.T_product_img"
+          style="height: 50px"
+          :src="row.T_product_img"
+          fit="cover"
+          @click="previewImg(row.T_product_img)"
+        />
+      </template>
+    </TableBase>
+    <Dialog ref="dialog" width="50%">
+      <el-image :src="url" :zoom-rate="1.2" :preview-src-list="srcList" fit="cover" />
+    </Dialog>
+  </div>
+</template>
+
+<style scoped lang="scss">
+.Device {
+  .input-suffix {
+    width: 100%;
+    .inline-flex {
+      white-space: nowrap;
+    }
+    .w-50 {
+      width: 14.5rem;
+    }
+  }
+}
+</style>

+ 127 - 0
src/views/storehouse/inventory/InStorage.vue

@@ -0,0 +1,127 @@
+<script setup lang="ts">
+import { ref, reactive, onMounted } from 'vue'
+import { GlobalStore } from '@/stores/index'
+import Dialog from '@/components/dialog/Dialog.vue'
+import TableBase from '@/components/TableBase/index.vue'
+import type { ColumnProps } from '@/components/TableBase/interface/index'
+import { Storehouse_StockIn_List, Storehouse_Depot_List } from '@/api/storehouse/index'
+import { View } from '@element-plus/icons-vue'
+import InStorageForm from './InStorageForm.vue'
+
+const globalStore = GlobalStore()
+const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
+
+const columns: ColumnProps[] = [
+  { type: 'index', label: '序号', width: 80 },
+  { prop: 'T_number', label: '入库单号' },
+  { prop: 'T_submit_name', label: '经办人' },
+  { prop: 'T_depot_name', label: '入库仓库' },
+  { prop: 'T_date', label: '入库日期' },
+  { prop: 'operation', label: '操作', width: 260, fixed: 'right' }
+]
+
+// 查看图片
+const url = ref('')
+const srcList = ref<any[]>([])
+const dialog = ref<InstanceType<typeof Dialog> | null>(null)
+const previewImg = (str: string) => {
+  dialog.value?.DialogOpen()
+  url.value = str
+  srcList.value.push(str)
+}
+
+// 搜索
+const initParam = reactive({
+  User_tokey: globalStore.GET_User_tokey,
+  T_date: '',
+  T_state: ''
+})
+const searchHandle = () => {
+  console.log(initParam)
+
+  // TableRef.value?.searchTable()
+}
+
+// 拿到仓库列表
+const options = ref()
+const getDepotList = async () => {
+  const res: any = await Storehouse_Depot_List({ User_tokey: globalStore.GET_User_tokey, page: 1, page_z: 999 })
+  options.value = res.Data.Data
+}
+onMounted(() => {
+  getDepotList()
+})
+</script>
+
+<template>
+  <div class="InStorage">
+    <TableBase ref="TableRef" :columns="columns" :requestApi="Storehouse_StockIn_List" :initParam="initParam">
+      <template #table-header>
+        <div class="input-suffix">
+          <el-row :gutter="20" style="margin-bottom: 0">
+            <el-col :xl="7" :lg="9" :md="11">
+              <span class="inline-flex items-center">入库日期:</span>
+              <el-date-picker
+                v-model="initParam.T_date"
+                type="daterange"
+                range-separator="~"
+                start-placeholder="开始时间"
+                end-placeholder="结束时间"
+                format="YYYY-MM-DD"
+                value-format="YYYY-MM-DD"
+                class="w-50 m-2"
+              />
+            </el-col>
+            <el-col :xl="14" :lg="12" :md="11">
+              <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.T_State" :label="item.T_name" :value="item.T_State" />
+              </el-select>
+              <el-button type="primary" @click="searchHandle">搜索</el-button>
+            </el-col>
+            <el-col :xl="3" :lg="3" :md="4" class="btn"><el-button type="primary">入库</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 type="danger" effect="dark"> 未出库 </el-tag>
+      </template>
+      <template #T_product_img="{ row }">
+        <el-image
+          v-if="row.T_product_img"
+          style="height: 50px"
+          :src="row.T_product_img"
+          fit="cover"
+          @click="previewImg(row.T_product_img)"
+        />
+      </template>
+      <template #right="{ row }">
+        <el-button link type="success" size="small" :icon="View">详情</el-button>
+      </template>
+    </TableBase>
+    <Dialog ref="dialog" width="50%">
+      <el-image :src="url" :zoom-rate="1.2" :preview-src-list="srcList" fit="cover" />
+    </Dialog>
+    <InStorageForm />
+  </div>
+</template>
+
+<style scoped lang="scss">
+.InStorage {
+  .input-suffix {
+    width: 100%;
+    .inline-flex {
+      white-space: nowrap;
+    }
+    .w-50 {
+      width: 12.5rem;
+    }
+    .btn {
+      .el-button {
+        padding: 0 20px;
+      }
+    }
+  }
+}
+</style>

+ 6 - 0
src/views/storehouse/inventory/InStorageForm.vue

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

+ 7 - 0
src/views/storehouse/inventory/index.vue

@@ -0,0 +1,7 @@
+<template>
+  <router-view></router-view>
+</template>
+
+<script setup lang="ts"></script>
+
+<style scoped></style>

+ 31 - 3
src/views/storehouse/sales/ContractDetail.vue

@@ -4,6 +4,7 @@ import { useRoute, useRouter } from 'vue-router'
 import { GlobalStore } from '@/stores/index'
 import { ElMessage } from 'element-plus'
 import { Storehouse_Contract_Get, Storehouse_Contract_Approval } from '@/api/storehouse/index'
+
 interface InfoType {
   Id: number
   T_State: number
@@ -25,6 +26,7 @@ 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' },
@@ -75,6 +77,30 @@ onMounted(() => {
 })
 </script>
 
+<script lang="ts">
+import { defineComponent } from 'vue'
+
+const isSale = ref(false)
+const globalStore = GlobalStore()
+
+export default defineComponent({
+  beforeRouteEnter(to, from, next) {
+    let isRole = globalStore.GET_Flat_Menu.find((item: any) => item.path === 'contract')
+    //需要处理的逻辑
+    if (from.name !== 'ContractSale' && isRole) {
+      isSale.value = true
+    }
+    next()
+  },
+  beforeRouteLeave(to, from, next) {
+    setTimeout(() => {
+      isSale.value = false
+    }, 1000)
+    next()
+  }
+})
+</script>
+
 <template>
   <div class="contract-detail">
     <div class="info">
@@ -158,7 +184,7 @@ onMounted(() => {
           <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-text type="danger">{{ info?.T_money! }}</el-text>
           </el-col>
         </el-row>
 
@@ -195,8 +221,10 @@ onMounted(() => {
 
       <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 v-if="isSale" type="danger" round @click="contractApproval(2)">审核不通过</el-button>
+        <el-button v-if="info?.T_State === 3 && isSale" type="success" round @click="contractApproval(1)"
+          >审核通过</el-button
+        >
         <el-button type="primary" round @click="router.back()">返回</el-button>
       </div>
     </div>

+ 0 - 2
src/views/storehouse/sales/ContractForm.vue

@@ -1,7 +1,6 @@
 <script setup lang="ts">
 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 { Delete } from '@element-plus/icons-vue'
 import { GlobalStore } from '@/stores/index'
@@ -24,7 +23,6 @@ const globalStore = GlobalStore()
 const formLabelWidth = ref('120px')
 const ruleFormRef = ref<FormInstance>()
 const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
-const dialogRef = ref<InstanceType<typeof Dialog> | null>(null)
 const uploadRef = ref<InstanceType<typeof Upload> | null>(null)
 const selectTable = ref()
 const drawerProductRef = ref<InstanceType<typeof Drawer> | null>(null)

+ 12 - 9
src/views/storehouse/sales/ContractSale.vue

@@ -5,13 +5,9 @@ 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 { Edit, Delete, 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'
+import { Storehouse_Contract_Del, Storehouse_Contract_User_List } from '@/api/storehouse/index'
 
 const router = useRouter()
 const globalStore = GlobalStore()
@@ -23,7 +19,6 @@ const columns: ColumnProps[] = [
   { 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' }
 ]
@@ -116,11 +111,19 @@ const searchHandle = () => {
         <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
+          :disabled="row.T_State === 1"
+          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>
+        <el-button :disabled="row.T_State === 1" link type="danger" size="small" :icon="Delete" @click="UserDelete(row)"
+          >删除</el-button
+        >
       </template>
     </TableBase>
     <ContractForm ref="ContractFormRef" @onTableList="updateOnTableList" />