280 lines
7.5 KiB
Vue
280 lines
7.5 KiB
Vue
<template>
|
||
<page-container>
|
||
<!-- 页面操作栏 -->
|
||
<template #ops>
|
||
<a-row>
|
||
<a-col :span="6">
|
||
<a-input-search
|
||
v-model:value="searchKey"
|
||
:placeholder="`名称/编码/类型`"
|
||
allow-clear
|
||
enter-button
|
||
@search="loadData()"
|
||
></a-input-search>
|
||
</a-col>
|
||
<a-col :span="6">
|
||
<a-button type="primary" style="margin-left: 10px" @click="addOrEdit()">
|
||
<template #icon>
|
||
<icon-font type="icon-plus" />
|
||
</template>
|
||
添加
|
||
</a-button>
|
||
</a-col>
|
||
</a-row>
|
||
</template>
|
||
<!-- 页面表格内容 -->
|
||
<div style="min-height: calc(100vh - 305px)">
|
||
<!-- 表格行 -->
|
||
<a-table
|
||
:columns="columns"
|
||
:data-source="materialPage?.records"
|
||
bordered
|
||
:pagination="pagination"
|
||
:loading="loading"
|
||
row-key="key"
|
||
>
|
||
<!-- 操作按钮列 -->
|
||
<template #bodyCell="{ column, record }">
|
||
<template v-if="column.dataIndex === 'assignRule'">
|
||
{{ record.assignRule ? '是' : '否' }}
|
||
</template>
|
||
<template v-if="column.dataIndex === 'operation'">
|
||
<a-button type="link" :style="{ color: token.colorPrimary }" @click="addOrEdit(record)">
|
||
<template #icon>
|
||
<icon-font type="icon-edit" />
|
||
</template>
|
||
编辑
|
||
</a-button>
|
||
|
||
<a-button
|
||
v-if="record.assignRule === 'HIGH_VALUE'"
|
||
type="link"
|
||
:style="{ color: token.colorPrimary }"
|
||
@click="showPrintModal(record.id)"
|
||
>
|
||
<template #icon>
|
||
<icon-font type="icon-print" />
|
||
</template>
|
||
条码打印
|
||
</a-button>
|
||
|
||
<a-popconfirm :title="`确定需要删除物料 ${record.name} 吗?`" @confirm="remove(record.id)">
|
||
<a-button type="link" danger style="margin-left: 10px">
|
||
<template #icon>
|
||
<icon-font type="icon-delete" />
|
||
</template>
|
||
删除
|
||
</a-button>
|
||
</a-popconfirm>
|
||
</template>
|
||
</template>
|
||
</a-table>
|
||
</div>
|
||
</page-container>
|
||
<form-drawer
|
||
ref="formDrawer"
|
||
v-model="material"
|
||
:form-items="items"
|
||
:config="formConfig"
|
||
:title="modalTitle"
|
||
@ok="doSave"
|
||
/>
|
||
<!-- 打印条码弹窗 -->
|
||
<a-modal
|
||
v-model:open="openPrint"
|
||
title="条形码打印"
|
||
width="100%"
|
||
wrap-class-name="full-modal"
|
||
@ok="closePrint"
|
||
@cancel="closePrint"
|
||
>
|
||
<printCode ref="printcodeRef" :material-id="materialIdRef"></printCode>
|
||
</a-modal>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import FormDrawer from '@/components/form-render/form-drawer.vue'
|
||
import api from '@/api'
|
||
import { IPage } from '@/api/api'
|
||
import { notification, theme } from 'ant-design-vue'
|
||
import { config, formItems } from './form'
|
||
import { FormDataType } from '@/components/form-render/form-render-types'
|
||
import printCode from './print-code.vue'
|
||
import { TreeDataNode } from 'ant-design-vue/es/vc-tree-select/interface'
|
||
|
||
const { useToken } = theme
|
||
const { token } = useToken()
|
||
const searchKey = ref('')
|
||
const openPrint = ref(false)
|
||
const materialPage = ref<IPage<material.Material>>()
|
||
const loading = ref(false)
|
||
const materialIdRef = ref<number>()
|
||
const printcodeRef = ref()
|
||
|
||
//类型树
|
||
|
||
const types = ref<Array<TreeDataNode>>([])
|
||
api.materialApi.type.trees((data) => {
|
||
types.value = children(data)
|
||
})
|
||
const children = (res: Array<material.TypeTree>): Array<TreeDataNode> => {
|
||
return res.map((areaTree) => ({
|
||
label: areaTree.label,
|
||
value: areaTree.value,
|
||
children: areaTree.children ? children(areaTree.children) : [],
|
||
key: areaTree.value,
|
||
}))
|
||
}
|
||
|
||
// 加载数据的方法
|
||
const loadData = async (page = 1, size = 10) => {
|
||
loading.value = true
|
||
api.materialApi.material.materials(
|
||
{ page: page || materialPage.value?.current, size: size || materialPage.value?.size, key: searchKey.value },
|
||
(data) => {
|
||
loading.value = false
|
||
materialPage.value = data
|
||
},
|
||
)
|
||
}
|
||
//初始加载
|
||
loadData()
|
||
|
||
//表格列
|
||
const columns = [
|
||
{
|
||
title: '物料序号',
|
||
dataIndex: 'key',
|
||
customRender: ({ index }: { index: number }) => `${index + 1}`,
|
||
},
|
||
{
|
||
title: '物料编码',
|
||
dataIndex: 'code',
|
||
},
|
||
{
|
||
title: '物料名称',
|
||
dataIndex: 'name',
|
||
},
|
||
{
|
||
title: '价格',
|
||
dataIndex: 'price',
|
||
},
|
||
{
|
||
title: '物料类型',
|
||
dataIndex: 'type',
|
||
},
|
||
{
|
||
title: '物料型号',
|
||
dataIndex: 'spec',
|
||
},
|
||
{
|
||
title: '是否赋码',
|
||
dataIndex: 'assignRule',
|
||
},
|
||
{
|
||
title: '备注',
|
||
dataIndex: 'description',
|
||
},
|
||
{
|
||
title: '操作',
|
||
dataIndex: 'operation',
|
||
width: 400,
|
||
},
|
||
]
|
||
|
||
//分页信息
|
||
const pagination = computed(() => {
|
||
return {
|
||
current: materialPage.value?.current,
|
||
pageSize: materialPage.value?.size,
|
||
total: materialPage.value?.total,
|
||
onChange: (page: number, pageSize: number) => {
|
||
loadData(page, pageSize)
|
||
},
|
||
}
|
||
})
|
||
|
||
const material = ref<Partial<material.Material>>({})
|
||
|
||
//表单
|
||
const formDrawer = ref<typeof FormDrawer>()
|
||
|
||
const formConfig = computed(() => {
|
||
return config
|
||
})
|
||
//表单配置
|
||
const items = computed(() => {
|
||
return formItems(types.value)
|
||
})
|
||
|
||
//弹窗标题
|
||
const modalTitle = computed(() => {
|
||
return material.value.id ? '编辑物料' : '添加物料'
|
||
})
|
||
|
||
//新增或编辑,只是打开弹窗
|
||
const addOrEdit = (u?: Record<string, unknown>) => {
|
||
/*
|
||
1. const addOrEdit = (u?: Record<string, unknown>) => { - 这里定义了一个名为 addOrEdit 的箭头函数,
|
||
它接受一个可选参数 u。这个参数被定义为 Record<string, unknown> 类型,
|
||
这意味着它是一个对象,其键是字符串,值可以是任何类型的数据。? 表示这个参数是可选的。
|
||
2. material.value = { ...(u ?? { channels: 3 }) } - 这一行的作用是更新 material 变量的值。
|
||
这里使用了 ES6 的解构赋值和空值合并运算符(??)。如果传入的参数 u 存在且不是 null 或 undefined,
|
||
则将 u 的所有属性复制到一个新的对象中;如果 u 是 null 或 undefined,则使用 { channels: 3 } 作为默认值。
|
||
然后,这个新对象被赋值给 material.value。这里的 material 很可能是一个响应式变量,通常在 Vue.js 框架中使用,用来表示数据模型的一部分,
|
||
value 属性则用来访问或修改这个响应式变量的实际值。
|
||
3. formDrawer.value?.show() - 这一行代码尝试调用 formDrawer 对象的 show 方法来显示表单抽屉。
|
||
这里使用了可选链操作符(?.),这表示只有当 formDrawer 和 formDrawer.value 都存在(即不是 null 或 undefined)时,才会调用 show 方法。
|
||
这是为了避免因访问不存在的对象属性而引发错误。
|
||
*/
|
||
// material.value = { ...(u ?? { channels: 3 }) }
|
||
material.value = { ...u } // 如果 u 存在,则使用 u 的值;否则使用空对象 {}
|
||
formDrawer.value?.show()
|
||
}
|
||
|
||
//保存
|
||
const doSave = (_data: FormDataType) => {
|
||
api.materialApi.material.saveOrUpdateMaterial(_data as unknown as material.Material, () => {
|
||
formDrawer.value?.close()
|
||
notification.success({
|
||
message: '操作成功',
|
||
description: '物料信息保存成功,页面将自动刷新!',
|
||
onClose: () => {
|
||
loadData(1)
|
||
},
|
||
})
|
||
})
|
||
}
|
||
|
||
//删除
|
||
const remove = (id: number) => {
|
||
api.materialApi.material.deleteMaterial(id, () => {
|
||
notification.success({
|
||
message: '操作成功',
|
||
description: '物料信息删除成功,页面将自动刷新!',
|
||
onClose: () => {
|
||
loadData(1)
|
||
},
|
||
})
|
||
})
|
||
}
|
||
|
||
// 打开打印弹窗
|
||
const showPrintModal = (applyId: number) => {
|
||
openPrint.value = true
|
||
materialIdRef.value = applyId
|
||
}
|
||
|
||
// 关闭打印弹窗
|
||
const closePrint = () => {
|
||
openPrint.value = false
|
||
printcodeRef.value.clearContent()
|
||
}
|
||
</script>
|
||
|
||
<style lang="less">
|
||
.notshow {
|
||
display: none;
|
||
}
|
||
</style>
|