|
@@ -1,5 +1,5 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, reactive } from 'vue'
|
|
|
+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'
|
|
@@ -8,8 +8,17 @@ 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_Product_List } from '@/api/storehouse/index'
|
|
|
-// import { Storehouse_IotCard_Add, Storehouse_IotCard_Edit } from '@/api/storehouse/index'
|
|
|
+import {
|
|
|
+ Storehouse_Product_List,
|
|
|
+ Storehouse_IotCard_Edit,
|
|
|
+ Storehouse_ProductClass_List,
|
|
|
+ Storehouse_Product_Model_List,
|
|
|
+ Storehouse_Product_Name_List
|
|
|
+} from '@/api/storehouse/index'
|
|
|
+import { debounce } from '@/utils/common'
|
|
|
+import { ElMessageBox, ElMessage } from 'element-plus'
|
|
|
+import { default as vElTableInfiniteScroll } from 'el-table-infinite-scroll'
|
|
|
+import { log } from 'console'
|
|
|
|
|
|
const isNew = ref(true)
|
|
|
const globalStore = GlobalStore()
|
|
@@ -19,10 +28,15 @@ 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 TableProductRef = ref<InstanceType<typeof TableBase> | null>(null)
|
|
|
+const drawerProductRef = ref<InstanceType<typeof Drawer> | null>(null)
|
|
|
|
|
|
const validate_T_product = (rule: any, value: any, callback: any) => {
|
|
|
+ console.log(value)
|
|
|
+
|
|
|
if (form.T_type === 1 && value === '') {
|
|
|
callback(new Error('请选择产品明细'))
|
|
|
+ } else if (value.includes(undefined)) {
|
|
|
+ callback(new Error('请填写产品数量'))
|
|
|
} else {
|
|
|
callback()
|
|
|
}
|
|
@@ -41,6 +55,7 @@ const callbackDrawer = (done: Fn) => {
|
|
|
resetForm(ruleFormRef.value)
|
|
|
done()
|
|
|
}
|
|
|
+const callbackProductDrawer = (done: Fn) => done()
|
|
|
|
|
|
const resetForm = (formEl: FormInstance | undefined) => {
|
|
|
if (!formEl) return
|
|
@@ -48,12 +63,23 @@ const resetForm = (formEl: FormInstance | undefined) => {
|
|
|
}
|
|
|
|
|
|
// 添加仓库名称
|
|
|
+interface FormType {
|
|
|
+ T_id: string
|
|
|
+ T_number: string
|
|
|
+ T_customer: string
|
|
|
+ T_type: any
|
|
|
+ T_product: any
|
|
|
+ T_money: string
|
|
|
+ T_date: string
|
|
|
+ T_remark: string
|
|
|
+ T_pdf: string
|
|
|
+}
|
|
|
type Fn = () => void
|
|
|
-const form = reactive({
|
|
|
+const form = reactive<FormType>({
|
|
|
T_id: '',
|
|
|
T_number: '',
|
|
|
T_customer: '',
|
|
|
- T_type: null,
|
|
|
+ T_type: '',
|
|
|
T_product: '',
|
|
|
T_money: '',
|
|
|
T_date: '',
|
|
@@ -74,66 +100,128 @@ const openDrawer = (type: string, row?: any) => {
|
|
|
drawerRef.value?.openDrawer()
|
|
|
}
|
|
|
|
|
|
-// const AddUserName = (formEl: FormInstance | undefined) => {
|
|
|
-// if (!formEl) return
|
|
|
-// formEl.validate(async valid => {
|
|
|
-// if (valid) {
|
|
|
-// let res: any = {}
|
|
|
-// if (isNew.value) {
|
|
|
-// console.log(form)
|
|
|
-// res = await Storehouse_IotCard_Add({ User_tokey: globalStore.GET_User_tokey, ...form })
|
|
|
-// } else {
|
|
|
-// res = await Storehouse_IotCard_Edit({
|
|
|
-// User_tokey: globalStore.GET_User_tokey,
|
|
|
-// ...form
|
|
|
-// })
|
|
|
-// }
|
|
|
-// if (res.Code === 200) {
|
|
|
-// ElMessage.success(`${isNew.value ? '添加' : '修改'}物联网卡成功!!`)
|
|
|
-// nextTick(() => {
|
|
|
-// drawerRef.value?.closeDrawer()
|
|
|
-// TableRef.value?.getTableList()
|
|
|
-// resetForm(ruleFormRef.value)
|
|
|
-// isNew.value = true
|
|
|
-// })
|
|
|
-// }
|
|
|
-// } else {
|
|
|
-// return 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 = {}
|
|
|
+ if (isNew.value) {
|
|
|
+ console.log(form)
|
|
|
+ // res = await Storehouse_IotCard_Add({ User_tokey: globalStore.GET_User_tokey, ...form })
|
|
|
+ } else {
|
|
|
+ res = await Storehouse_IotCard_Edit({
|
|
|
+ User_tokey: globalStore.GET_User_tokey,
|
|
|
+ ...form
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (res.Code === 200) {
|
|
|
+ ElMessage.success(`${isNew.value ? '添加' : '修改'}物联网卡成功!!`)
|
|
|
+ nextTick(() => {
|
|
|
+ drawerRef.value?.closeDrawer()
|
|
|
+ // TableRef.value?.getTableList()
|
|
|
+ resetForm(ruleFormRef.value)
|
|
|
+ isNew.value = true
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
|
|
|
-// const AddUserName = () => {
|
|
|
-// console.log(tableData)
|
|
|
-// }
|
|
|
// 增加产品
|
|
|
// dialog
|
|
|
const initParam = reactive({
|
|
|
User_tokey: globalStore.GET_User_tokey,
|
|
|
T_name: '',
|
|
|
T_model: '',
|
|
|
- T_class: ''
|
|
|
+ T_class: '',
|
|
|
+ page: 0,
|
|
|
+ page_z: 20
|
|
|
})
|
|
|
-const classOptions = reactive<any[]>([])
|
|
|
-const modelOptions = reactive<any[]>([])
|
|
|
+const classOptions = ref<any[]>([])
|
|
|
+const modelOptions = ref<any[]>([])
|
|
|
+// 获取产品分类
|
|
|
+const getProductClassList = async () => {
|
|
|
+ const res: any = await Storehouse_ProductClass_List({ page: 1, page_z: 999 })
|
|
|
+ classOptions.value = res.Data.Data
|
|
|
+}
|
|
|
+// 获取产品型号
|
|
|
+const getProductModelList = async () => {
|
|
|
+ const res: any = await Storehouse_Product_Model_List({ T_name: initParam.T_name })
|
|
|
+ console.log(res)
|
|
|
+ modelOptions.value = res.Data.map((item: any, index: number) => {
|
|
|
+ return {
|
|
|
+ value: item,
|
|
|
+ index: index
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
const AddProductionDetailed = () => {
|
|
|
- dialogRef.value?.DialogOpen()
|
|
|
+ // getProductList()
|
|
|
+ !classOptions.value.length && getProductClassList()
|
|
|
+ drawerProductRef.value?.openDrawer()
|
|
|
+}
|
|
|
+// 搜索名称
|
|
|
+const searchNameHandle = async () => {
|
|
|
+ console.log(initParam)
|
|
|
+ const res = await Storehouse_Product_Name_List({ T_name: initParam.T_name, T_class: initParam.T_class })
|
|
|
+ console.log(res)
|
|
|
+}
|
|
|
+// 搜索模型
|
|
|
+const searchModelHandle = () => {
|
|
|
+ total = 0
|
|
|
+ initParam.page = 1
|
|
|
+ tableProductData.value = []
|
|
|
+ getProductList()
|
|
|
+ // console.log(initParam)
|
|
|
}
|
|
|
const searchHandle = () => {
|
|
|
//
|
|
|
}
|
|
|
+// 保存选中的数据id,row-key就是要指定一个key标识这一行的数据
|
|
|
+const getRowKey = (row: any) => {
|
|
|
+ return row.Id
|
|
|
+}
|
|
|
+// 选中的产品
|
|
|
+const ProductselectionChange = (row: any[]) => {
|
|
|
+ tableData.value = row
|
|
|
+}
|
|
|
|
|
|
-const tableData = reactive<any[]>([])
|
|
|
+// 加载第二个抽屉数据
|
|
|
+const load = () => {
|
|
|
+ if (initParam.page && total === tableProductData.value.length) {
|
|
|
+ ElMessage.warning('没有更多数据了!!')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ initParam.page++
|
|
|
+ getProductList()
|
|
|
+}
|
|
|
+let total = 0
|
|
|
+const tableProductData = ref<any[]>([])
|
|
|
+const getProductList = async () => {
|
|
|
+ const res: any = await Storehouse_Product_List({ ...initParam })
|
|
|
+ console.log(res)
|
|
|
+ tableProductData.value.push(...res.Data.Data)
|
|
|
+ total = res.Data.Num
|
|
|
+}
|
|
|
+
|
|
|
+const tableData = ref<any[]>([])
|
|
|
const columns = [
|
|
|
{ type: 'index', label: '序号', width: 80, align: 'center ' },
|
|
|
- { label: '产品图片', prop: 'T_img', align: 'center ' },
|
|
|
+ { label: '产品图片', prop: 'T_img', align: 'center ', name: 'T_img' },
|
|
|
{ label: '产品名称', prop: 'T_name', align: 'center ' },
|
|
|
{ label: '产品分类', prop: 'T_class_name', align: 'center ' },
|
|
|
{ label: '产品型号', prop: 'T_model', align: 'center ' },
|
|
|
{ label: '产品规格', prop: 'T_spec', align: 'center ' },
|
|
|
- { label: '是否关联SN', prop: 'T_relation_sn', align: 'center ', width: 120 },
|
|
|
+ { label: '是否关联SN', prop: 'T_relation_sn', align: 'center ', width: 120, name: 'T_relation_sn' },
|
|
|
{ label: '*数量', prop: 'count', align: 'center ', name: 'count' },
|
|
|
- { label: '备注', prop: 'id', align: 'center ' },
|
|
|
+ { label: '备注', prop: 'T_remark', align: 'center ' },
|
|
|
{ prop: 'operation', label: '操作', width: 80, fixed: 'right' }
|
|
|
]
|
|
|
|
|
@@ -142,12 +230,41 @@ const productColumns = [
|
|
|
{ prop: 'T_img', label: '产品图片', name: 'T_img' },
|
|
|
{ prop: 'T_name', label: '产品名称' },
|
|
|
{ prop: 'T_class_name', label: '产品分类' },
|
|
|
- { prop: 'T_model', label: '产品型号' },
|
|
|
+ { prop: 'T_model', label: '产品型号', ellipsis: true },
|
|
|
{ prop: 'T_spec', label: '产品规格' },
|
|
|
{ prop: 'T_relation_sn', label: '关联SN', name: 'T_relation_sn' },
|
|
|
- { prop: 'T_name', label: '更新时间' }
|
|
|
+ { prop: 'T_remark', label: '备注', ellipsis: true }
|
|
|
]
|
|
|
|
|
|
+// 自动搜索
|
|
|
+const autoSelect = ref('')
|
|
|
+let timeout: NodeJS.Timeout
|
|
|
+const querySearchAsync = async (queryString: string, cb: (arg: any) => void) => {
|
|
|
+ clearTimeout(timeout)
|
|
|
+ timeout = setTimeout(async () => {
|
|
|
+ const results = await getNameAsync(queryString)
|
|
|
+ console.log(autoSelect, queryString)
|
|
|
+ cb(results)
|
|
|
+ }, 2000)
|
|
|
+}
|
|
|
+
|
|
|
+const getNameAsync = async (str: string): Promise<any> => {
|
|
|
+ const res: any = await Storehouse_Product_Name_List({ T_name: str, T_class: initParam.T_class })
|
|
|
+ if (!res.Data) return
|
|
|
+ return res.Data.map((item: any, index: number) => {
|
|
|
+ return {
|
|
|
+ value: item,
|
|
|
+ index: index
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const handleSelect = (item: any) => {
|
|
|
+ console.log(item)
|
|
|
+ initParam.T_name = item.value
|
|
|
+ getProductModelList()
|
|
|
+}
|
|
|
+
|
|
|
defineExpose({
|
|
|
openDrawer
|
|
|
})
|
|
@@ -196,8 +313,13 @@ defineExpose({
|
|
|
<template #header v-if="item.prop === 'count'">
|
|
|
<span style="color: red">*数量</span>
|
|
|
</template>
|
|
|
- <template #default="{ row }" v-if="item.prop === item.name && item.prop">
|
|
|
- <el-input v-model.number="row.count" type="text" autocomplete="off" />
|
|
|
+ <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" />
|
|
|
+ <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'">
|
|
@@ -234,7 +356,7 @@ defineExpose({
|
|
|
placeholder="请输入备注信息"
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="上传附件:" :label-width="formLabelWidth" prop="T_type">
|
|
|
+ <el-form-item label="上传附件:" :label-width="formLabelWidth" prop="T_pdf">
|
|
|
<Upload
|
|
|
class="w-50"
|
|
|
ref="uploadRef"
|
|
@@ -252,61 +374,104 @@ defineExpose({
|
|
|
<div class="btn">
|
|
|
<el-divider>
|
|
|
<el-button>取消</el-button>
|
|
|
- <el-button v-if="isNew" color="#626aef">提交</el-button>
|
|
|
+ <el-button v-if="isNew" color="#626aef" @click="AddContract(ruleFormRef)">提交</el-button>
|
|
|
<el-button v-else color="#626aef">修改</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">
|
|
|
+ <template #header>
|
|
|
+ <div class="input-suffix">
|
|
|
+ <el-row :gutter="20" style="margin-bottom: 0">
|
|
|
+ <el-col :xl="5" :lg="8" :md="10" class="d-flex">
|
|
|
+ <span class="inline-flex items-center">产品分类:</span>
|
|
|
+ <el-select v-model="initParam.T_class" clearable placeholder="请选择分类~">
|
|
|
+ <el-option v-for="item in classOptions" :key="item.Id" :label="item.T_name" :value="item.Id" />
|
|
|
+ </el-select>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xl="7" :lg="8" :md="10" class="d-flex">
|
|
|
+ <span class="inline-flex items-center">产品名称:</span>
|
|
|
+ <el-autocomplete
|
|
|
+ v-model="autoSelect"
|
|
|
+ clearable
|
|
|
+ :fetch-suggestions="querySearchAsync"
|
|
|
+ placeholder="Please input"
|
|
|
+ :debounce="2000"
|
|
|
+ @select="handleSelect"
|
|
|
+ />
|
|
|
+ </el-col>
|
|
|
+ <el-col :xl="7" :lg="8" :md="12" class="d-flex">
|
|
|
+ <span class="inline-flex items-center">产品型号:</span>
|
|
|
+ <el-select v-model="initParam.T_model" clearable placeholder="请选择型号~">
|
|
|
+ <el-option
|
|
|
+ v-for="item in modelOptions"
|
|
|
+ :key="item.index"
|
|
|
+ :label="item.value"
|
|
|
+ :value="item.index"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ <el-button type="primary" @click="searchModelHandle">搜索</el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <el-table
|
|
|
+ border
|
|
|
+ :row-key="getRowKey"
|
|
|
+ :data="tableProductData"
|
|
|
+ style="width: 100%; height: 99%"
|
|
|
+ v-el-table-infinite-scroll="load"
|
|
|
+ @selection-change="ProductselectionChange"
|
|
|
+ >
|
|
|
+ <template v-for="item in productColumns" :key="item">
|
|
|
+ <el-table-column
|
|
|
+ v-if="item.type === 'index' || item.type === 'selection'"
|
|
|
+ align="center"
|
|
|
+ v-bind="item"
|
|
|
+ />
|
|
|
+ <el-table-column v-if="!item.ellipsis && item.prop" v-bind="item">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <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-if="item.ellipsis && item.prop === 'T_model'" align="center" v-bind="item">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-tooltip effect="dark" :content="row.T_model" placement="bottom">
|
|
|
+ {{ row.T_model }}
|
|
|
+ </el-tooltip>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column v-if="item.ellipsis && item.prop === 'T_remark'" align="center" v-bind="item">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-tooltip effect="customized" placement="left">
|
|
|
+ <template #content>
|
|
|
+ <div class="tooltip-content">{{ row.T_remark }}</div>
|
|
|
+ </template>
|
|
|
+ {{ row.T_remark }}
|
|
|
+ </el-tooltip>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </template>
|
|
|
+ </el-table>
|
|
|
+ </el-card>
|
|
|
+ </Drawer>
|
|
|
</el-form>
|
|
|
</Drawer>
|
|
|
- <Dialog ref="dialogRef" width="80%">
|
|
|
- <template #header> 选择产品 </template>
|
|
|
- <TableBase
|
|
|
- ref="TableProductRef"
|
|
|
- :columns="productColumns"
|
|
|
- :requestApi="Storehouse_Product_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" class="d-flex">
|
|
|
- <span class="inline-flex items-center">产品分类:</span>
|
|
|
- <el-select v-model="initParam.T_class" clearable placeholder="请选择分类~">
|
|
|
- <el-option v-for="item in classOptions" :key="item.Id" :label="item.T_name" :value="item.Id" />
|
|
|
- </el-select>
|
|
|
- </el-col>
|
|
|
- <el-col :xl="6" :lg="8" :md="10" class="d-flex">
|
|
|
- <span class="inline-flex items-center">产品名称:</span>
|
|
|
- <el-input
|
|
|
- v-model="initParam.T_name"
|
|
|
- type="text"
|
|
|
- placeholder="按产品名称、产品型号搜索"
|
|
|
- @change="searchHandle"
|
|
|
- />
|
|
|
- </el-col>
|
|
|
- <el-col :xl="7" :lg="8" :md="12" class="d-flex">
|
|
|
- <span class="inline-flex items-center">产品型号:</span>
|
|
|
- <el-select v-model="initParam.T_model" clearable placeholder="请选择型号~">
|
|
|
- <el-option v-for="item in modelOptions" :key="item.Id" :label="item.T_name" :value="item.Id" />
|
|
|
- </el-select>
|
|
|
- <el-button type="primary" @click="searchHandle">搜索</el-button>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <template #T_img="{ row }">
|
|
|
- <el-image style="height: 50px" :src="row.T_img" fit="cover" />
|
|
|
- </template>
|
|
|
- <template #T_relation_sn="{ row }">
|
|
|
- <el-tag v-if="row.T_relation_sn === 1" effect="dark">是</el-tag>
|
|
|
- <el-tag v-else type="success" effect="dark">否</el-tag>
|
|
|
- </template>
|
|
|
- </TableBase>
|
|
|
- </Dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
+.tooltip-content {
|
|
|
+ max-width: 500px;
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
.contract-form {
|
|
|
:deep(.el-table--border .el-table__cell) {
|
|
|
border-right: 0;
|
|
@@ -315,6 +480,13 @@ defineExpose({
|
|
|
:deep(.card) {
|
|
|
border: 0;
|
|
|
}
|
|
|
+ .box-card {
|
|
|
+ height: 100%;
|
|
|
+ :deep(.el-card__body) {
|
|
|
+ height: calc(100% - 70px);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
.btn {
|
|
|
margin-top: 32px;
|
|
|
display: flex;
|