生产管理(未完成1)
This commit is contained in:
56
src/apis/bom/bom.ts
Normal file
56
src/apis/bom/bom.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import http from '@/utils/http'
|
||||
|
||||
const BASE_URL = '/bom/bom'
|
||||
|
||||
export interface BomResp {
|
||||
id: string
|
||||
bomCode: string
|
||||
bomName: string
|
||||
bomType: string
|
||||
remark: string
|
||||
createUser: string
|
||||
createTime: string
|
||||
updateUser: string
|
||||
updateTime: string
|
||||
createUserString: string
|
||||
updateUserString: string
|
||||
disabled: boolean
|
||||
}
|
||||
export interface BomQuery {
|
||||
bomCode: string | undefined
|
||||
bomName: string | undefined
|
||||
bomType: string | undefined
|
||||
createTime: string | undefined
|
||||
sort: Array<string>
|
||||
}
|
||||
export interface BomPageQuery extends BomQuery, PageQuery {}
|
||||
|
||||
/** @desc 查询BOM物料清单(单)列表 */
|
||||
export function listBom(query: BomPageQuery) {
|
||||
return http.get<PageRes<BomResp[]>>(`${BASE_URL}`, query)
|
||||
}
|
||||
|
||||
/** @desc 查询BOM物料清单(单)详情 */
|
||||
export function getBom(id: string) {
|
||||
return http.get<BomResp>(`${BASE_URL}/${id}`)
|
||||
}
|
||||
|
||||
/** @desc 新增BOM物料清单(单) */
|
||||
export function addBom(data: any) {
|
||||
return http.post(`${BASE_URL}`, data)
|
||||
}
|
||||
|
||||
/** @desc 修改BOM物料清单(单) */
|
||||
export function updateBom(data: any, id: string) {
|
||||
return http.put(`${BASE_URL}/${id}`, data)
|
||||
}
|
||||
|
||||
/** @desc 删除BOM物料清单(单) */
|
||||
export function deleteBom(id: string) {
|
||||
return http.del(`${BASE_URL}/${id}`)
|
||||
}
|
||||
|
||||
/** @desc 导出BOM物料清单(单) */
|
||||
export function exportBom(query: BomQuery) {
|
||||
return http.download(`${BASE_URL}/export`, query)
|
||||
}
|
||||
86
src/apis/process/process.ts
Normal file
86
src/apis/process/process.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import http from '@/utils/http'
|
||||
|
||||
const BASE_URL = '/process/process'
|
||||
|
||||
export interface ProcessResp {
|
||||
id: string
|
||||
processCode: string
|
||||
processName: string
|
||||
processType: string
|
||||
processCategory: string
|
||||
isKeyProcess: string
|
||||
isSpecialProcess: string
|
||||
isQualityGate: string
|
||||
standardDurationMinutes: string
|
||||
setupDurationMinutes: string
|
||||
waitingDurationMinutes: string
|
||||
moveDurationMinutes: string
|
||||
defaultWorkCenter: string
|
||||
requiredSkillLevel: string
|
||||
minOperatorCount: string
|
||||
parameterTemplate: string
|
||||
qualityCheckRequired: string
|
||||
defaultCheckRate: string
|
||||
allowableDefectRate: string
|
||||
needMaterial: string
|
||||
materialIssueMethod: string
|
||||
status: string
|
||||
version: string
|
||||
sortOrder: string
|
||||
sopUrl: string
|
||||
videoUrl: string
|
||||
remark: string
|
||||
attachmentIds: string
|
||||
createUser: string
|
||||
createTime: string
|
||||
updateUser: string
|
||||
updateTime: string
|
||||
createUserString: string
|
||||
updateUserString: string
|
||||
disabled: boolean
|
||||
}
|
||||
export interface ProcessQuery {
|
||||
processCode: string | undefined
|
||||
processName: string | undefined
|
||||
processType: string | undefined
|
||||
isKeyProcess: string | undefined
|
||||
isSpecialProcess: string | undefined
|
||||
isQualityGate: string | undefined
|
||||
qualityCheckRequired: string | undefined
|
||||
needMaterial: string | undefined
|
||||
status: string | undefined
|
||||
version: string | undefined
|
||||
createTime: string | undefined
|
||||
sort: Array<string>
|
||||
}
|
||||
export interface ProcessPageQuery extends ProcessQuery, PageQuery {}
|
||||
|
||||
/** @desc 查询工序基础信息列表 */
|
||||
export function listProcess(query: ProcessPageQuery) {
|
||||
return http.get<PageRes<ProcessResp[]>>(`${BASE_URL}`, query)
|
||||
}
|
||||
|
||||
/** @desc 查询工序基础信息详情 */
|
||||
export function getProcess(id: string) {
|
||||
return http.get<ProcessResp>(`${BASE_URL}/${id}`)
|
||||
}
|
||||
|
||||
/** @desc 新增工序基础信息 */
|
||||
export function addProcess(data: any) {
|
||||
return http.post(`${BASE_URL}`, data)
|
||||
}
|
||||
|
||||
/** @desc 修改工序基础信息 */
|
||||
export function updateProcess(data: any, id: string) {
|
||||
return http.put(`${BASE_URL}/${id}`, data)
|
||||
}
|
||||
|
||||
/** @desc 删除工序基础信息 */
|
||||
export function deleteProcess(id: string) {
|
||||
return http.del(`${BASE_URL}/${id}`)
|
||||
}
|
||||
|
||||
/** @desc 导出工序基础信息 */
|
||||
export function exportProcess(query: ProcessQuery) {
|
||||
return http.download(`${BASE_URL}/export`, query)
|
||||
}
|
||||
@@ -38,7 +38,7 @@ export function listProductionLine(query: ProductionLinePageQuery) {
|
||||
|
||||
/** @desc 查询产线基础详情 */
|
||||
export function getProductionLine(id: string) {
|
||||
return http.get<ProductionLineDetailResp>(`${BASE_URL}/${id}`)
|
||||
return http.get<ProductionLineResp>(`${BASE_URL}/${id}`)
|
||||
}
|
||||
|
||||
/** @desc 新增产线基础 */
|
||||
|
||||
62
src/apis/routing/routing.ts
Normal file
62
src/apis/routing/routing.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import http from '@/utils/http'
|
||||
|
||||
const BASE_URL = '/routing/routing'
|
||||
|
||||
export interface RoutingResp {
|
||||
id: string
|
||||
routingCode: string
|
||||
routingName: string
|
||||
productId: string
|
||||
productCategory: string
|
||||
lineId: string
|
||||
version: string
|
||||
isActive: string
|
||||
status: string
|
||||
remark: string
|
||||
createUser: string
|
||||
createTime: string
|
||||
updateUser: string
|
||||
updateTime: string
|
||||
createUserString: string
|
||||
updateUserString: string
|
||||
disabled: boolean
|
||||
}
|
||||
export interface RoutingQuery {
|
||||
routingCode: string | undefined
|
||||
routingName: string | undefined
|
||||
version: string | undefined
|
||||
isActive: string | undefined
|
||||
status: string | undefined
|
||||
sort: Array<string>
|
||||
}
|
||||
export interface RoutingPageQuery extends RoutingQuery, PageQuery {}
|
||||
|
||||
/** @desc 查询工艺路线主列表 */
|
||||
export function listRouting(query: RoutingPageQuery) {
|
||||
return http.get<PageRes<RoutingResp[]>>(`${BASE_URL}`, query)
|
||||
}
|
||||
|
||||
/** @desc 查询工艺路线主详情 */
|
||||
export function getRouting(id: string) {
|
||||
return http.get<RoutingResp>(`${BASE_URL}/${id}`)
|
||||
}
|
||||
|
||||
/** @desc 新增工艺路线主 */
|
||||
export function addRouting(data: any) {
|
||||
return http.post(`${BASE_URL}`, data)
|
||||
}
|
||||
|
||||
/** @desc 修改工艺路线主 */
|
||||
export function updateRouting(data: any, id: string) {
|
||||
return http.put(`${BASE_URL}/${id}`, data)
|
||||
}
|
||||
|
||||
/** @desc 删除工艺路线主 */
|
||||
export function deleteRouting(id: string) {
|
||||
return http.del(`${BASE_URL}/${id}`)
|
||||
}
|
||||
|
||||
/** @desc 导出工艺路线主 */
|
||||
export function exportRouting(query: RoutingQuery) {
|
||||
return http.download(`${BASE_URL}/export`, query)
|
||||
}
|
||||
129
src/views/bom/bom/BomAddModal.vue
Normal file
129
src/views/bom/bom/BomAddModal.vue
Normal file
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
:title="title"
|
||||
:mask-closable="false"
|
||||
:esc-to-close="false"
|
||||
:width="width >= 600 ? 600 : '100%'"
|
||||
draggable
|
||||
@before-ok="save"
|
||||
@close="reset"
|
||||
>
|
||||
<GiForm ref="formRef" v-model="form" :columns="columns" />
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Message } from '@arco-design/web-vue'
|
||||
import { useWindowSize } from '@vueuse/core'
|
||||
import { getBom, addBom, updateBom } from '@/apis/bom/bom'
|
||||
import { type ColumnItem, GiForm } from '@/components/GiForm'
|
||||
import { useResetReactive } from '@/hooks'
|
||||
import { useDict } from '@/hooks/app'
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'save-success'): void
|
||||
}>()
|
||||
|
||||
const { width } = useWindowSize()
|
||||
|
||||
const dataId = ref('')
|
||||
const visible = ref(false)
|
||||
const isUpdate = computed(() => !!dataId.value)
|
||||
const title = computed(() => (isUpdate.value ? '修改BOM物料' : '新增BOM物料'))
|
||||
const formRef = ref<InstanceType<typeof GiForm>>()
|
||||
|
||||
const [form, resetForm] = useResetReactive({})
|
||||
|
||||
|
||||
const { bom_type } = useDict('bom_type')
|
||||
|
||||
const columns: ColumnItem[] = reactive([
|
||||
{
|
||||
label: '编号',
|
||||
field: 'bomCode',
|
||||
type: 'input',
|
||||
props: {
|
||||
placeholder: '请输入BOM编码',
|
||||
maxLength: 50
|
||||
},
|
||||
span: 24,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '名称',
|
||||
field: 'bomName',
|
||||
type: 'input',
|
||||
props: {
|
||||
placeholder: '请输入BOM名称',
|
||||
maxLength: 50
|
||||
},
|
||||
span: 24,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '类型',
|
||||
field: 'bomType',
|
||||
type: 'select',
|
||||
span: 24,
|
||||
required: true,
|
||||
props: {
|
||||
options: bom_type
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '说明',
|
||||
field: 'remark',
|
||||
type: 'textarea',
|
||||
props: {
|
||||
rows: 4
|
||||
},
|
||||
span: 24,
|
||||
},
|
||||
])
|
||||
|
||||
// 重置
|
||||
const reset = () => {
|
||||
formRef.value?.formRef?.resetFields()
|
||||
resetForm()
|
||||
}
|
||||
|
||||
// 保存
|
||||
const save = async () => {
|
||||
try {
|
||||
const isInvalid = await formRef.value?.formRef?.validate()
|
||||
if (isInvalid) return false
|
||||
if (isUpdate.value) {
|
||||
await updateBom(form, dataId.value)
|
||||
Message.success('修改成功')
|
||||
} else {
|
||||
await addBom(form)
|
||||
Message.success('新增成功')
|
||||
}
|
||||
emit('save-success')
|
||||
return true
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 新增
|
||||
const onAdd = async () => {
|
||||
reset()
|
||||
dataId.value = ''
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
// 修改
|
||||
const onUpdate = async (id: string) => {
|
||||
reset()
|
||||
dataId.value = id
|
||||
const { data } = await getBom(id)
|
||||
Object.assign(form, data)
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
defineExpose({ onAdd, onUpdate })
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
50
src/views/bom/bom/BomDetailDrawer.vue
Normal file
50
src/views/bom/bom/BomDetailDrawer.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<a-drawer v-model:visible="visible" title="BOM物料清单(单)详情" :width="width >= 600 ? 600 : '100%'" :footer="false">
|
||||
<a-descriptions :column="2" size="large" class="general-description">
|
||||
<a-descriptions-item label="主键ID">{{ dataDetail?.id }}</a-descriptions-item>
|
||||
<a-descriptions-item label="编号">{{ dataDetail?.bomCode }}</a-descriptions-item>
|
||||
<a-descriptions-item label="名称">{{ dataDetail?.bomName }}</a-descriptions-item>
|
||||
<a-descriptions-item label="类型">
|
||||
<GiCellTag :value="dataDetail?.bomType" :dict="bom_type" />
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="说明">{{ dataDetail?.remark }}</a-descriptions-item>
|
||||
<a-descriptions-item label="">{{ dataDetail?.createUser }}</a-descriptions-item>
|
||||
<a-descriptions-item label="创建人">{{ dataDetail?.createUserString }}</a-descriptions-item>
|
||||
<a-descriptions-item label="">{{ dataDetail?.createTime }}</a-descriptions-item>
|
||||
<a-descriptions-item label="">{{ dataDetail?.updateUser }}</a-descriptions-item>
|
||||
<a-descriptions-item label="修改人">{{ dataDetail?.updateUserString }}</a-descriptions-item>
|
||||
<a-descriptions-item label="">{{ dataDetail?.updateTime }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useWindowSize } from '@vueuse/core'
|
||||
import { type BomResp, getBom as getDetail } from '@/apis/bom/bom'
|
||||
import {useDict} from "@/hooks/app";
|
||||
|
||||
|
||||
const { bom_type } = useDict('bom_type')
|
||||
const { width } = useWindowSize()
|
||||
|
||||
const dataId = ref('')
|
||||
const dataDetail = ref<BomResp>()
|
||||
const visible = ref(false)
|
||||
|
||||
// 查询详情
|
||||
const getDataDetail = async () => {
|
||||
const { data } = await getDetail(dataId.value)
|
||||
dataDetail.value = data
|
||||
}
|
||||
|
||||
// 打开
|
||||
const onOpen = async (id: string) => {
|
||||
dataId.value = id
|
||||
await getDataDetail()
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
defineExpose({ onOpen })
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
157
src/views/bom/bom/index.vue
Normal file
157
src/views/bom/bom/index.vue
Normal file
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<div class="gi_table_page">
|
||||
<GiTable
|
||||
row-key="id"
|
||||
:data="dataList"
|
||||
:columns="columns"
|
||||
:loading="loading"
|
||||
:scroll="{ x: '100%', y: '100%', minWidth: 1000 }"
|
||||
:pagination="pagination"
|
||||
:disabled-tools="['size']"
|
||||
:disabled-column-keys="['name']"
|
||||
@refresh="search"
|
||||
>
|
||||
<template #toolbar-left>
|
||||
<a-input-search v-model="queryForm.bomCode" placeholder="请输入编号" allow-clear @search="search" />
|
||||
<a-input-search v-model="queryForm.bomName" placeholder="请输入名称" allow-clear @search="search" />
|
||||
<a-select
|
||||
v-model="queryForm.bomType"
|
||||
placeholder="请选择类型"
|
||||
:options="bomTypeDict"
|
||||
allow-clear
|
||||
style="width: 150px"
|
||||
@change="search"
|
||||
/>
|
||||
<a-input-search v-model="queryForm.createTime" placeholder="请输入" allow-clear @search="search" />
|
||||
<a-button @click="reset">
|
||||
<template #icon><icon-refresh /></template>
|
||||
<template #default>重置</template>
|
||||
</a-button>
|
||||
</template>
|
||||
<template #toolbar-right>
|
||||
<a-button v-permission="['bom:bom:add']" type="primary" @click="onAdd">
|
||||
<template #icon><icon-plus /></template>
|
||||
<template #default>新增</template>
|
||||
</a-button>
|
||||
<a-button v-permission="['bom:bom:export']" @click="onExport">
|
||||
<template #icon><icon-download /></template>
|
||||
<template #default>导出</template>
|
||||
</a-button>
|
||||
</template>
|
||||
<template #bomType="{ record }">
|
||||
<GiCellTag :value="record.bomType" :dict="bom_type" />
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<a-space>
|
||||
<a-link v-permission="['bom:bom:detail']" title="详情" @click="onDetail(record)">详情</a-link>
|
||||
<a-link v-permission="['bom:bom:update']" title="修改" @click="onUpdate(record)">修改</a-link>
|
||||
<a-link
|
||||
v-permission="['bom:bom:delete']"
|
||||
status="danger"
|
||||
:disabled="record.disabled"
|
||||
:title="record.disabled ? '不可删除' : '删除'"
|
||||
@click="onDelete(record)"
|
||||
>
|
||||
删除
|
||||
</a-link>
|
||||
</a-space>
|
||||
</template>
|
||||
</GiTable>
|
||||
|
||||
<BomAddModal ref="BomAddModalRef" @save-success="search" />
|
||||
<BomDetailDrawer ref="BomDetailDrawerRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import BomAddModal from './BomAddModal.vue'
|
||||
import BomDetailDrawer from './BomDetailDrawer.vue'
|
||||
import { type BomResp, type BomQuery, deleteBom, exportBom, listBom } from '@/apis/bom/bom'
|
||||
import type { TableInstanceColumns } from '@/components/GiTable/type'
|
||||
import { useDownload, useTable } from '@/hooks'
|
||||
import GiCellTag from '@/components/GiCell/GiCellTag.vue'
|
||||
import { isMobile } from '@/utils'
|
||||
import has from '@/utils/has'
|
||||
import {useDict} from "@/hooks/app";
|
||||
|
||||
const { bom_type } = useDict('bom_type')
|
||||
|
||||
defineOptions({ name: 'Bom' })
|
||||
|
||||
|
||||
const queryForm = reactive<BomQuery>({
|
||||
bomCode: undefined,
|
||||
bomName: undefined,
|
||||
bomType: undefined,
|
||||
createTime: undefined,
|
||||
sort: ['id,desc']
|
||||
})
|
||||
|
||||
const {
|
||||
tableData: dataList,
|
||||
loading,
|
||||
pagination,
|
||||
search,
|
||||
handleDelete
|
||||
} = useTable((page) => listBom({ ...queryForm, ...page }), { immediate: true })
|
||||
const columns = ref<TableInstanceColumns[]>([
|
||||
{ title: 'BOM编码', dataIndex: 'bomCode', slotName: 'bomCode' },
|
||||
{ title: 'BOM名称', dataIndex: 'bomName', slotName: 'bomName' },
|
||||
{ title: '类型', dataIndex: 'bomType', slotName: 'bomType', align: 'center' },
|
||||
{ title: '说明', dataIndex: 'remark', slotName: 'remark' },
|
||||
{ title: '创建人', dataIndex: 'createUserString', slotName: 'createUser' },
|
||||
{ title: '创建时间', dataIndex: 'createTime', slotName: 'createTime' },
|
||||
{ title: '更新人', dataIndex: 'updateUserString', slotName: 'updateUser', show: false },
|
||||
{ title: '更新时间', dataIndex: 'updateTime', slotName: 'updateTime', show: false },
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
slotName: 'action',
|
||||
width: 160,
|
||||
align: 'center',
|
||||
fixed: !isMobile() ? 'right' : undefined,
|
||||
show: has.hasPermOr(['bom:bom:detail', 'bom:bom:update', 'bom:bom:delete'])
|
||||
}
|
||||
]);
|
||||
|
||||
// 重置
|
||||
const reset = () => {
|
||||
queryForm.bomCode = undefined
|
||||
queryForm.bomName = undefined
|
||||
queryForm.bomType = undefined
|
||||
queryForm.createTime = undefined
|
||||
search()
|
||||
}
|
||||
|
||||
// 删除
|
||||
const onDelete = (record: BomResp) => {
|
||||
return handleDelete(() => deleteBom(record.id), {
|
||||
content: `是否确定删除该条数据?`,
|
||||
showModal: true
|
||||
})
|
||||
}
|
||||
|
||||
// 导出
|
||||
const onExport = () => {
|
||||
useDownload(() => exportBom(queryForm))
|
||||
}
|
||||
|
||||
const BomAddModalRef = ref<InstanceType<typeof BomAddModal>>()
|
||||
// 新增
|
||||
const onAdd = () => {
|
||||
BomAddModalRef.value?.onAdd()
|
||||
}
|
||||
|
||||
// 修改
|
||||
const onUpdate = (record: BomResp) => {
|
||||
BomAddModalRef.value?.onUpdate(record.id)
|
||||
}
|
||||
|
||||
const BomDetailDrawerRef = ref<InstanceType<typeof BomDetailDrawer>>()
|
||||
// 详情
|
||||
const onDetail = (record: BomResp) => {
|
||||
BomDetailDrawerRef.value?.onOpen(record.id)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
293
src/views/process/process/ProcessAddModal.vue
Normal file
293
src/views/process/process/ProcessAddModal.vue
Normal file
@@ -0,0 +1,293 @@
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
:title="title"
|
||||
:mask-closable="false"
|
||||
:esc-to-close="false"
|
||||
:width="width >= 700 ? 700 : '100%'"
|
||||
draggable
|
||||
@before-ok="save"
|
||||
@close="reset"
|
||||
>
|
||||
<GiForm ref="formRef" v-model="form" :columns="columns" />
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="tsx">
|
||||
import { Message } from '@arco-design/web-vue'
|
||||
import { useWindowSize } from '@vueuse/core'
|
||||
import { getProcess, addProcess, updateProcess } from '@/apis/process/process'
|
||||
import { type ColumnItem, GiForm } from '@/components/GiForm'
|
||||
import { useResetReactive } from '@/hooks'
|
||||
import { useDict } from '@/hooks/app'
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'save-success'): void
|
||||
}>()
|
||||
|
||||
const { width } = useWindowSize()
|
||||
|
||||
const dataId = ref('')
|
||||
const visible = ref(false)
|
||||
const isUpdate = computed(() => !!dataId.value)
|
||||
const title = computed(() => (isUpdate.value ? '修改工序基础信息' : '新增工序基础信息'))
|
||||
const formRef = ref<InstanceType<typeof GiForm>>()
|
||||
|
||||
const { process_type, yse_or_no, process_status, material_issue_method, skill_level } = useDict(
|
||||
'process_type',
|
||||
'yse_or_no',
|
||||
'process_status',
|
||||
'material_issue_method',
|
||||
'skill_level'
|
||||
)
|
||||
|
||||
const [form, resetForm] = useResetReactive({
|
||||
processCode: '',
|
||||
processName: '',
|
||||
processType: '',
|
||||
processCategory: '',
|
||||
isKeyProcess: '',
|
||||
isSpecialProcess: '',
|
||||
standardDurationMinutes: '',
|
||||
setupDurationMinutes: '',
|
||||
waitingDurationMinutes: '',
|
||||
moveDurationMinutes: '',
|
||||
requiredSkillLevel: '',
|
||||
minOperatorCount: '',
|
||||
qualityCheckRequired: '',
|
||||
defaultCheckRate: '',
|
||||
allowableDefectRate: '',
|
||||
needMaterial: '',
|
||||
materialIssueMethod: '',
|
||||
status: '',
|
||||
remark: '',
|
||||
attachmentIds: ''
|
||||
})
|
||||
|
||||
const columns: ColumnItem[] = reactive([
|
||||
{
|
||||
label: '工序编号',
|
||||
field: 'processCode',
|
||||
type: 'input',
|
||||
span: 24,
|
||||
required: true,
|
||||
placeholder: '请输入工序编号'
|
||||
},
|
||||
{
|
||||
label: '工序名称',
|
||||
field: 'processName',
|
||||
type: 'input',
|
||||
span: 24,
|
||||
required: true,
|
||||
placeholder: '请输入工序名称'
|
||||
},
|
||||
{
|
||||
label: '工序类型',
|
||||
field: 'processType',
|
||||
type: 'select',
|
||||
span: 24,
|
||||
required: true,
|
||||
props: {
|
||||
options: process_type,
|
||||
},
|
||||
placeholder: '请选择工序类型'
|
||||
},
|
||||
{
|
||||
label: '工序分类',
|
||||
field: 'processCategory',
|
||||
type: 'input',
|
||||
span: 24,
|
||||
placeholder: '如:SMT、组装、测试'
|
||||
},
|
||||
{
|
||||
label: '是否关键工序',
|
||||
field: 'isKeyProcess',
|
||||
type: 'select',
|
||||
span: 12,
|
||||
required: true,
|
||||
props: {
|
||||
options: yse_or_no,
|
||||
},
|
||||
placeholder: '是否关键工序'
|
||||
},
|
||||
{
|
||||
label: '特殊工序',
|
||||
field: 'isSpecialProcess',
|
||||
type: 'select',
|
||||
span: 12,
|
||||
required: true,
|
||||
props: {
|
||||
options: yse_or_no,
|
||||
},
|
||||
placeholder: '是否特殊工序'
|
||||
},
|
||||
{
|
||||
label: '需要质检',
|
||||
field: 'qualityCheckRequired',
|
||||
type: 'select',
|
||||
span: 12,
|
||||
required: true,
|
||||
props: {
|
||||
options: yse_or_no,
|
||||
},
|
||||
placeholder: '是否需要质检'
|
||||
},
|
||||
{
|
||||
label: '标准工时(分钟)',
|
||||
field: 'standardDurationMinutes',
|
||||
type: 'input-number',
|
||||
span: 12,
|
||||
placeholder: '请输入标准工时'
|
||||
},
|
||||
{
|
||||
label: '准备时间(分钟)',
|
||||
field: 'setupDurationMinutes',
|
||||
type: 'input-number',
|
||||
span: 12,
|
||||
placeholder: '请输入准备时间'
|
||||
},
|
||||
{
|
||||
label: '等待时间(分钟)',
|
||||
field: 'waitingDurationMinutes',
|
||||
type: 'input-number',
|
||||
span: 12,
|
||||
placeholder: '请输入等待时间'
|
||||
},
|
||||
{
|
||||
label: '搬运时间(分钟)',
|
||||
field: 'moveDurationMinutes',
|
||||
type: 'input-number',
|
||||
span: 12,
|
||||
placeholder: '请输入搬运时间'
|
||||
},
|
||||
{
|
||||
label: '技能等级',
|
||||
field: 'requiredSkillLevel',
|
||||
type: 'select',
|
||||
span: 12,
|
||||
dict: skill_level,
|
||||
placeholder: '请选择技能等级'
|
||||
},
|
||||
{
|
||||
label: '最少人数',
|
||||
field: 'minOperatorCount',
|
||||
type: 'input-number',
|
||||
span: 12,
|
||||
props: {
|
||||
min: 1,
|
||||
},
|
||||
placeholder: '请输入最少人数'
|
||||
},
|
||||
{
|
||||
label: '抽检比例(%)',
|
||||
field: 'defaultCheckRate',
|
||||
type: 'input-number',
|
||||
span: 12,
|
||||
props: {
|
||||
min: 0,
|
||||
step: 0.1
|
||||
},
|
||||
slots: {
|
||||
append: () => (
|
||||
<span style={{ width: '30px', textAlign: 'center' }}>%</span>
|
||||
),
|
||||
},
|
||||
placeholder: '请输入抽检比例'
|
||||
},
|
||||
{
|
||||
label: '不良率(%)',
|
||||
field: 'allowableDefectRate',
|
||||
type: 'input-number',
|
||||
span: 12,
|
||||
props: {
|
||||
min: 0,
|
||||
step: 0.1
|
||||
},
|
||||
placeholder: '请输入不良率'
|
||||
},
|
||||
{
|
||||
label: '需要领料',
|
||||
field: 'needMaterial',
|
||||
type: 'select',
|
||||
span: 12,
|
||||
required: true,
|
||||
props: {
|
||||
options: yse_or_no,
|
||||
},
|
||||
placeholder: '是否需要领料'
|
||||
},
|
||||
{
|
||||
label: '发料方式',
|
||||
field: 'materialIssueMethod',
|
||||
type: 'select',
|
||||
span: 12,
|
||||
props: {
|
||||
options: material_issue_method,
|
||||
},
|
||||
placeholder: '请选择发料方式'
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
field: 'status',
|
||||
type: 'select',
|
||||
span: 12,
|
||||
required: true,
|
||||
props: {
|
||||
options: process_status,
|
||||
},
|
||||
placeholder: '请选择状态'
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
field: 'remark',
|
||||
type: 'textarea',
|
||||
span: 24,
|
||||
placeholder: '请输入备注'
|
||||
}
|
||||
])
|
||||
|
||||
// 重置
|
||||
const reset = () => {
|
||||
formRef.value?.formRef?.resetFields()
|
||||
resetForm()
|
||||
}
|
||||
|
||||
// 保存
|
||||
const save = async () => {
|
||||
try {
|
||||
const isInvalid = await formRef.value?.formRef?.validate()
|
||||
if (isInvalid) return false
|
||||
if (isUpdate.value) {
|
||||
await updateProcess(form, dataId.value)
|
||||
Message.success('修改成功')
|
||||
} else {
|
||||
await addProcess(form)
|
||||
Message.success('新增成功')
|
||||
}
|
||||
emit('save-success')
|
||||
return true
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 新增
|
||||
const onAdd = async () => {
|
||||
reset()
|
||||
dataId.value = ''
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
// 修改
|
||||
const onUpdate = async (id: string) => {
|
||||
reset()
|
||||
dataId.value = id
|
||||
const { data } = await getProcess(id)
|
||||
Object.assign(form, data)
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
defineExpose({ onAdd, onUpdate })
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
83
src/views/process/process/ProcessDetailDrawer.vue
Normal file
83
src/views/process/process/ProcessDetailDrawer.vue
Normal file
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<a-drawer v-model:visible="visible" title="工序基础信息详情" :width="width >= 600 ? 600 : '100%'" :footer="false">
|
||||
<a-descriptions :column="2" size="large" class="general-description">
|
||||
<a-descriptions-item label="工序编号">{{ dataDetail?.processCode }}</a-descriptions-item>
|
||||
<a-descriptions-item label="工序名称">{{ dataDetail?.processName }}</a-descriptions-item>
|
||||
<a-descriptions-item label="工序类型">
|
||||
<GiCellTag :value="dataDetail?.processType" :dict="process_type" />
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="工序分类">{{ dataDetail?.processCategory }}</a-descriptions-item>
|
||||
<a-descriptions-item label="关键工序">
|
||||
<GiCellTag :value="dataDetail?.isKeyProcess" :dict="yse_or_no" />
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="特殊工序">
|
||||
<GiCellTag :value="dataDetail?.isSpecialProcess" :dict="yse_or_no" />
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="需要质检">
|
||||
<GiCellTag :value="dataDetail?.qualityCheckRequired" :dict="yse_or_no" />
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="标准工时(分钟)">{{ dataDetail?.standardDurationMinutes }}</a-descriptions-item>
|
||||
<a-descriptions-item label="准备时间(分钟)">{{ dataDetail?.setupDurationMinutes }}</a-descriptions-item>
|
||||
<a-descriptions-item label="等待时间(分钟)">{{ dataDetail?.waitingDurationMinutes }}</a-descriptions-item>
|
||||
<a-descriptions-item label="搬运时间(分钟)">{{ dataDetail?.moveDurationMinutes }}</a-descriptions-item>
|
||||
<a-descriptions-item label="技能等级">
|
||||
<GiCellTag :value="dataDetail?.requiredSkillLevel" :dict="skill_level" />
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="最少人数">{{ dataDetail?.minOperatorCount }}</a-descriptions-item>
|
||||
<a-descriptions-item label="抽检比例(%)">{{ dataDetail?.defaultCheckRate }}</a-descriptions-item>
|
||||
<a-descriptions-item label="不良率(%)">{{ dataDetail?.allowableDefectRate }}</a-descriptions-item>
|
||||
<a-descriptions-item label="需要领料">
|
||||
<GiCellTag :value="dataDetail?.needMaterial" :dict="yse_or_no" />
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="发料方式">
|
||||
<GiCellTag :value="dataDetail?.materialIssueMethod" :dict="material_issue_method" />
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="状态">
|
||||
<GiCellTag :value="dataDetail?.status" :dict="sys_normal_disable" />
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="备注">{{ dataDetail?.remark }}</a-descriptions-item>
|
||||
<a-descriptions-item label="创建人">{{ dataDetail?.createUserString }}</a-descriptions-item>
|
||||
<a-descriptions-item label="创建时间">{{ dataDetail?.createTime }}</a-descriptions-item>
|
||||
<a-descriptions-item label="修改人">{{ dataDetail?.updateUserString }}</a-descriptions-item>
|
||||
<a-descriptions-item label="修改时间">{{ dataDetail?.updateTime }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useWindowSize } from '@vueuse/core'
|
||||
import { type ProcessResp, getProcess as getDetail } from '@/apis/process/process'
|
||||
import GiCellTag from '@/components/GiCell/GiCellTag.vue'
|
||||
import { useDict } from '@/hooks/app'
|
||||
|
||||
const { width } = useWindowSize()
|
||||
|
||||
const { process_type, yse_or_no, sys_normal_disable, material_issue_method, skill_level } = useDict(
|
||||
'process_type',
|
||||
'yse_or_no',
|
||||
'sys_normal_disable',
|
||||
'material_issue_method',
|
||||
'skill_level'
|
||||
)
|
||||
|
||||
const dataId = ref('')
|
||||
const dataDetail = ref<ProcessResp>()
|
||||
const visible = ref(false)
|
||||
|
||||
// 查询详情
|
||||
const getDataDetail = async () => {
|
||||
const { data } = await getDetail(dataId.value)
|
||||
dataDetail.value = data
|
||||
}
|
||||
|
||||
// 打开
|
||||
const onOpen = async (id: string) => {
|
||||
dataId.value = id
|
||||
await getDataDetail()
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
defineExpose({ onOpen })
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
255
src/views/process/process/index.vue
Normal file
255
src/views/process/process/index.vue
Normal file
@@ -0,0 +1,255 @@
|
||||
<template>
|
||||
<div class="gi_table_page">
|
||||
<GiTable
|
||||
title="工序基础信息管理"
|
||||
row-key="id"
|
||||
:data="dataList"
|
||||
:columns="columns"
|
||||
:loading="loading"
|
||||
:scroll="{ x: '100%', y: '100%', minWidth: 1000 }"
|
||||
:pagination="pagination"
|
||||
:disabled-tools="['size']"
|
||||
:disabled-column-keys="['name']"
|
||||
@refresh="search"
|
||||
>
|
||||
<template #toolbar-left>
|
||||
<a-input-search v-model="queryForm.processCode" placeholder="请输入工序编号" allow-clear @search="search" />
|
||||
<a-input-search v-model="queryForm.processName" placeholder="请输入工序名称" allow-clear @search="search" />
|
||||
<a-select
|
||||
v-model="queryForm.processType"
|
||||
placeholder="请选择工序类型"
|
||||
:options="process_type"
|
||||
allow-clear
|
||||
style="width: 160px"
|
||||
@change="search"
|
||||
/>
|
||||
<a-select
|
||||
v-model="queryForm.isKeyProcess"
|
||||
placeholder="是否关键工序"
|
||||
:options="yse_or_no"
|
||||
allow-clear
|
||||
style="width: 150px"
|
||||
@change="search"
|
||||
/>
|
||||
<a-select
|
||||
v-model="queryForm.isSpecialProcess"
|
||||
placeholder="是否特殊工序"
|
||||
:options="yse_or_no"
|
||||
allow-clear
|
||||
style="width: 150px"
|
||||
@change="search"
|
||||
/>
|
||||
<a-select
|
||||
v-model="queryForm.isQualityGate"
|
||||
placeholder="是否质量门禁"
|
||||
:options="yse_or_no"
|
||||
allow-clear
|
||||
style="width: 150px"
|
||||
@change="search"
|
||||
/>
|
||||
<a-select
|
||||
v-model="queryForm.qualityCheckRequired"
|
||||
placeholder="是否需要质检"
|
||||
:options="yse_or_no"
|
||||
allow-clear
|
||||
style="width: 150px"
|
||||
@change="search"
|
||||
/>
|
||||
<a-select
|
||||
v-model="queryForm.needMaterial"
|
||||
placeholder="是否需要领料"
|
||||
:options="yse_or_no"
|
||||
allow-clear
|
||||
style="width: 150px"
|
||||
@change="search"
|
||||
/>
|
||||
<a-select
|
||||
v-model="queryForm.status"
|
||||
placeholder="请选择状态"
|
||||
:options="process_status"
|
||||
allow-clear
|
||||
style="width: 150px"
|
||||
@change="search"
|
||||
/>
|
||||
<DateRangePicker v-model="queryForm.createTime" @change="search" />
|
||||
<a-button @click="reset">
|
||||
<template #icon><icon-refresh /></template>
|
||||
<template #default>重置</template>
|
||||
</a-button>
|
||||
</template>
|
||||
<template #toolbar-right>
|
||||
<a-button v-permission="['process:process:add']" type="primary" @click="onAdd">
|
||||
<template #icon><icon-plus /></template>
|
||||
<template #default>新增</template>
|
||||
</a-button>
|
||||
<a-button v-permission="['process:process:export']" @click="onExport">
|
||||
<template #icon><icon-download /></template>
|
||||
<template #default>导出</template>
|
||||
</a-button>
|
||||
</template>
|
||||
<template #processType="{ record }">
|
||||
<GiCellTag :value="record.processType" :dict="process_type" />
|
||||
</template>
|
||||
<template #isKeyProcess="{ record }">
|
||||
<GiCellTag :value="record.isKeyProcess" :dict="yse_or_no" />
|
||||
</template>
|
||||
<template #isSpecialProcess="{ record }">
|
||||
<GiCellTag :value="record.isSpecialProcess" :dict="yse_or_no" />
|
||||
</template>
|
||||
<template #isQualityGate="{ record }">
|
||||
<GiCellTag :value="record.isQualityGate" :dict="yse_or_no" />
|
||||
</template>
|
||||
<template #qualityCheckRequired="{ record }">
|
||||
<GiCellTag :value="record.qualityCheckRequired" :dict="yse_or_no" />
|
||||
</template>
|
||||
<template #needMaterial="{ record }">
|
||||
<GiCellTag :value="record.needMaterial" :dict="yse_or_no" />
|
||||
</template>
|
||||
<template #materialIssueMethod="{ record }">
|
||||
<GiCellTag :value="record.materialIssueMethod" :dict="material_issue_method" />
|
||||
</template>
|
||||
<template #requiredSkillLevel="{ record }">
|
||||
<GiCellTag :value="record.requiredSkillLevel" :dict="skill_level" />
|
||||
</template>
|
||||
<template #status="{ record }">
|
||||
<GiCellTag :value="record.status" :dict="process_status" />
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<a-space>
|
||||
<a-link v-permission="['process:process:detail']" title="详情" @click="onDetail(record)">详情</a-link>
|
||||
<a-link v-permission="['process:process:update']" title="修改" @click="onUpdate(record)">修改</a-link>
|
||||
<a-link v-permission="['process:process:update']" title="所需用料" @click="onUpdate(record)">所需用料</a-link>
|
||||
<a-link
|
||||
v-permission="['process:process:delete']"
|
||||
status="danger"
|
||||
:disabled="record.disabled"
|
||||
:title="record.disabled ? '不可删除' : '删除'"
|
||||
@click="onDelete(record)"
|
||||
>
|
||||
删除
|
||||
</a-link>
|
||||
</a-space>
|
||||
</template>
|
||||
</GiTable>
|
||||
|
||||
<ProcessAddModal ref="ProcessAddModalRef" @save-success="search" />
|
||||
<ProcessDetailDrawer ref="ProcessDetailDrawerRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import ProcessAddModal from './ProcessAddModal.vue'
|
||||
import ProcessDetailDrawer from './ProcessDetailDrawer.vue'
|
||||
import { type ProcessResp, type ProcessQuery, deleteProcess, exportProcess, listProcess } from '@/apis/process/process'
|
||||
import type { TableInstanceColumns } from '@/components/GiTable/type'
|
||||
import GiCellTag from '@/components/GiCell/GiCellTag.vue'
|
||||
import DateRangePicker from '@/components/DateRangePicker/index.vue'
|
||||
import { useDownload, useTable } from '@/hooks'
|
||||
import { useDict } from '@/hooks/app'
|
||||
import { isMobile } from '@/utils'
|
||||
import has from '@/utils/has'
|
||||
|
||||
defineOptions({ name: 'Process' })
|
||||
|
||||
const { process_type, yse_or_no, process_status, material_issue_method, skill_level } = useDict(
|
||||
'process_type',
|
||||
'yse_or_no',
|
||||
'process_status',
|
||||
'material_issue_method',
|
||||
'skill_level'
|
||||
)
|
||||
|
||||
const queryForm = reactive<ProcessQuery>({
|
||||
processCode: undefined,
|
||||
processName: undefined,
|
||||
processType: undefined,
|
||||
isKeyProcess: undefined,
|
||||
isSpecialProcess: undefined,
|
||||
isQualityGate: undefined,
|
||||
qualityCheckRequired: undefined,
|
||||
needMaterial: undefined,
|
||||
status: undefined,
|
||||
version: undefined,
|
||||
createTime: undefined,
|
||||
sort: ['id,desc']
|
||||
})
|
||||
|
||||
const {
|
||||
tableData: dataList,
|
||||
loading,
|
||||
pagination,
|
||||
search,
|
||||
handleDelete
|
||||
} = useTable((page) => listProcess({ ...queryForm, ...page }), { immediate: true })
|
||||
const columns = ref<TableInstanceColumns[]>([
|
||||
{ title: '工序编号', dataIndex: 'processCode', slotName: 'processCode' },
|
||||
{ title: '工序名称', dataIndex: 'processName', slotName: 'processName' },
|
||||
{ title: '工序类型', dataIndex: 'processType', slotName: 'processType', align: 'center' },
|
||||
{ title: '工序分类', dataIndex: 'processCategory', slotName: 'processCategory' },
|
||||
{ title: '关键工序', dataIndex: 'isKeyProcess', slotName: 'isKeyProcess', align: 'center' },
|
||||
{ title: '特殊工序', dataIndex: 'isSpecialProcess', slotName: 'isSpecialProcess', align: 'center' },
|
||||
{ title: '需要质检', dataIndex: 'qualityCheckRequired', slotName: 'qualityCheckRequired', align: 'center' },
|
||||
{ title: '需要领料', dataIndex: 'needMaterial', slotName: 'needMaterial', align: 'center' },
|
||||
{ title: '状态', dataIndex: 'status', slotName: 'status', align: 'center' },
|
||||
{ title: '版本号', dataIndex: 'version', slotName: 'version' },
|
||||
{ title: '创建人', dataIndex: 'createUserString', slotName: 'createUser' , show: false},
|
||||
{ title: '创建时间', dataIndex: 'createTime', slotName: 'createTime', width: 180 },
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
slotName: 'action',
|
||||
width: 160,
|
||||
align: 'center',
|
||||
fixed: !isMobile() ? 'right' : undefined,
|
||||
show: has.hasPermOr(['process:process:detail', 'process:process:update', 'process:process:delete'])
|
||||
}
|
||||
]);
|
||||
|
||||
// 重置
|
||||
const reset = () => {
|
||||
queryForm.processCode = undefined
|
||||
queryForm.processName = undefined
|
||||
queryForm.processType = undefined
|
||||
queryForm.isKeyProcess = undefined
|
||||
queryForm.isSpecialProcess = undefined
|
||||
queryForm.isQualityGate = undefined
|
||||
queryForm.qualityCheckRequired = undefined
|
||||
queryForm.needMaterial = undefined
|
||||
queryForm.status = undefined
|
||||
queryForm.version = undefined
|
||||
queryForm.createTime = undefined
|
||||
search()
|
||||
}
|
||||
|
||||
// 删除
|
||||
const onDelete = (record: ProcessResp) => {
|
||||
return handleDelete(() => deleteProcess(record.id), {
|
||||
content: `是否确定删除该条数据?`,
|
||||
showModal: true
|
||||
})
|
||||
}
|
||||
|
||||
// 导出
|
||||
const onExport = () => {
|
||||
useDownload(() => exportProcess(queryForm))
|
||||
}
|
||||
|
||||
const ProcessAddModalRef = ref<InstanceType<typeof ProcessAddModal>>()
|
||||
// 新增
|
||||
const onAdd = () => {
|
||||
ProcessAddModalRef.value?.onAdd()
|
||||
}
|
||||
|
||||
// 修改
|
||||
const onUpdate = (record: ProcessResp) => {
|
||||
ProcessAddModalRef.value?.onUpdate(record.id)
|
||||
}
|
||||
|
||||
const ProcessDetailDrawerRef = ref<InstanceType<typeof ProcessDetailDrawer>>()
|
||||
// 详情
|
||||
const onDetail = (record: ProcessResp) => {
|
||||
ProcessDetailDrawerRef.value?.onOpen(record.id)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
149
src/views/routing/routing/RoutingAddModal.vue
Normal file
149
src/views/routing/routing/RoutingAddModal.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
:title="title"
|
||||
:mask-closable="false"
|
||||
:esc-to-close="false"
|
||||
:width="width >= 600 ? 600 : '100%'"
|
||||
draggable
|
||||
@before-ok="save"
|
||||
@close="reset"
|
||||
>
|
||||
<GiForm ref="formRef" v-model="form" :columns="columns" />
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Message } from '@arco-design/web-vue'
|
||||
import { useWindowSize } from '@vueuse/core'
|
||||
import { getRouting, addRouting, updateRouting } from '@/apis/routing/routing'
|
||||
import { type ColumnItem, GiForm } from '@/components/GiForm'
|
||||
import { useResetReactive } from '@/hooks'
|
||||
import { useDict } from '@/hooks/app'
|
||||
|
||||
const { yse_or_no, process_status } = useDict('yse_or_no', 'process_status')
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'save-success'): void
|
||||
}>()
|
||||
|
||||
const { width } = useWindowSize()
|
||||
|
||||
const dataId = ref('')
|
||||
const visible = ref(false)
|
||||
const isUpdate = computed(() => !!dataId.value)
|
||||
const title = computed(() => (isUpdate.value ? '修改工艺路线主' : '新增工艺路线主'))
|
||||
const formRef = ref<InstanceType<typeof GiForm>>()
|
||||
|
||||
const [form, resetForm] = useResetReactive({
|
||||
routingCode: '',
|
||||
routingName: '',
|
||||
productId: '',
|
||||
productCategory: '',
|
||||
lineId: '',
|
||||
version: '',
|
||||
isActive: '',
|
||||
status: '',
|
||||
remark: ''
|
||||
})
|
||||
|
||||
const columns: ColumnItem[] = reactive([
|
||||
{
|
||||
label: '工艺路线编码',
|
||||
field: 'routingCode',
|
||||
type: 'input',
|
||||
span: 24,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '工艺路线名称',
|
||||
field: 'routingName',
|
||||
type: 'input',
|
||||
span: 24,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '产品',
|
||||
field: 'productId',
|
||||
type: 'input',
|
||||
span: 24,
|
||||
},
|
||||
{
|
||||
label: '产线',
|
||||
field: 'lineId',
|
||||
type: 'input',
|
||||
span: 24,
|
||||
},
|
||||
{
|
||||
label: '是否启用',
|
||||
field: 'isActive',
|
||||
type: 'select',
|
||||
span: 24,
|
||||
required: true,
|
||||
props: {
|
||||
options: yse_or_no
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
field: 'status',
|
||||
type: 'select',
|
||||
span: 24,
|
||||
required: true,
|
||||
props: {
|
||||
options: process_status
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
field: 'remark',
|
||||
type: 'textarea',
|
||||
span: 24,
|
||||
},
|
||||
])
|
||||
|
||||
// 重置
|
||||
const reset = () => {
|
||||
formRef.value?.formRef?.resetFields()
|
||||
resetForm()
|
||||
}
|
||||
|
||||
// 保存
|
||||
const save = async () => {
|
||||
try {
|
||||
const isInvalid = await formRef.value?.formRef?.validate()
|
||||
if (isInvalid) return false
|
||||
if (isUpdate.value) {
|
||||
await updateRouting(form, dataId.value)
|
||||
Message.success('修改成功')
|
||||
} else {
|
||||
await addRouting(form)
|
||||
Message.success('新增成功')
|
||||
}
|
||||
emit('save-success')
|
||||
return true
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 新增
|
||||
const onAdd = async () => {
|
||||
reset()
|
||||
dataId.value = ''
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
// 修改
|
||||
const onUpdate = async (id: string) => {
|
||||
reset()
|
||||
dataId.value = id
|
||||
const { data } = await getRouting(id)
|
||||
Object.assign(form, data)
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
defineExpose({ onAdd, onUpdate })
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
56
src/views/routing/routing/RoutingDetailDrawer.vue
Normal file
56
src/views/routing/routing/RoutingDetailDrawer.vue
Normal file
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<a-drawer v-model:visible="visible" title="工艺路线主详情" :width="width >= 600 ? 600 : '100%'" :footer="false">
|
||||
<a-descriptions :column="2" size="large" class="general-description">
|
||||
<a-descriptions-item label="主键ID">{{ dataDetail?.id }}</a-descriptions-item>
|
||||
<a-descriptions-item label="工艺路线编码">{{ dataDetail?.routingCode }}</a-descriptions-item>
|
||||
<a-descriptions-item label="工艺路线名称">{{ dataDetail?.routingName }}</a-descriptions-item>
|
||||
<a-descriptions-item label="关联产品ID">{{ dataDetail?.productId }}</a-descriptions-item>
|
||||
<a-descriptions-item label="适用产品分类">{{ dataDetail?.productCategory }}</a-descriptions-item>
|
||||
<a-descriptions-item label="默认产线ID">{{ dataDetail?.lineId }}</a-descriptions-item>
|
||||
<a-descriptions-item label="版本号">{{ dataDetail?.version }}</a-descriptions-item>
|
||||
<a-descriptions-item label="是否启用">
|
||||
<GiCellTag :value="dataDetail?.isActive" :dict="yse_or_no" />
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="状态">
|
||||
<GiCellTag :value="dataDetail?.status" :dict="process_status" />
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="备注">{{ dataDetail?.remark }}</a-descriptions-item>
|
||||
<a-descriptions-item label="创建人">{{ dataDetail?.createUserString }}</a-descriptions-item>
|
||||
<a-descriptions-item label="创建时间">{{ dataDetail?.createTime }}</a-descriptions-item>
|
||||
<a-descriptions-item label="修改人">{{ dataDetail?.updateUserString }}</a-descriptions-item>
|
||||
<a-descriptions-item label="修改时间">{{ dataDetail?.updateTime }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useWindowSize } from '@vueuse/core'
|
||||
import { type RoutingResp, getRouting as getDetail } from '@/apis/routing/routing'
|
||||
import GiCellTag from '@/components/GiCell/GiCellTag.vue'
|
||||
import { useDict } from '@/hooks/app'
|
||||
|
||||
const { yse_or_no, process_status } = useDict('yse_or_no', 'process_status')
|
||||
|
||||
const { width } = useWindowSize()
|
||||
|
||||
const dataId = ref('')
|
||||
const dataDetail = ref<RoutingResp>()
|
||||
const visible = ref(false)
|
||||
|
||||
// 查询详情
|
||||
const getDataDetail = async () => {
|
||||
const { data } = await getDetail(dataId.value)
|
||||
dataDetail.value = data
|
||||
}
|
||||
|
||||
// 打开
|
||||
const onOpen = async (id: string) => {
|
||||
dataId.value = id
|
||||
await getDataDetail()
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
defineExpose({ onOpen })
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
160
src/views/routing/routing/index.vue
Normal file
160
src/views/routing/routing/index.vue
Normal file
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<div class="gi_table_page">
|
||||
<GiTable
|
||||
title="工艺路线主管理"
|
||||
row-key="id"
|
||||
:data="dataList"
|
||||
:columns="columns"
|
||||
:loading="loading"
|
||||
:scroll="{ x: '100%', y: '100%', minWidth: 1000 }"
|
||||
:pagination="pagination"
|
||||
:disabled-tools="['size']"
|
||||
:disabled-column-keys="['name']"
|
||||
@refresh="search"
|
||||
>
|
||||
<template #toolbar-left>
|
||||
<a-input-search v-model="queryForm.routingCode" placeholder="请输入工艺路线编码" allow-clear @search="search" />
|
||||
<a-input-search v-model="queryForm.routingName" placeholder="请输入工艺路线名称" allow-clear @search="search" />
|
||||
<a-input-search v-model="queryForm.version" placeholder="请输入版本号" allow-clear @search="search" />
|
||||
<a-input-search v-model="queryForm.isActive" placeholder="请输入是否启用" allow-clear @search="search" />
|
||||
<a-input-search v-model="queryForm.status" placeholder="请输入状态" allow-clear @search="search" />
|
||||
<a-button @click="reset">
|
||||
<template #icon><icon-refresh /></template>
|
||||
<template #default>重置</template>
|
||||
</a-button>
|
||||
</template>
|
||||
<template #toolbar-right>
|
||||
<a-button v-permission="['routing:routing:add']" type="primary" @click="onAdd">
|
||||
<template #icon><icon-plus /></template>
|
||||
<template #default>新增</template>
|
||||
</a-button>
|
||||
<a-button v-permission="['routing:routing:export']" @click="onExport">
|
||||
<template #icon><icon-download /></template>
|
||||
<template #default>导出</template>
|
||||
</a-button>
|
||||
</template>
|
||||
<template #isActive="{ record }">
|
||||
<GiCellTag :value="record.isActive" :dict="yse_or_no" />
|
||||
</template>
|
||||
<template #status="{ record }">
|
||||
<GiCellTag :value="record.status" :dict="process_status" />
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<a-space>
|
||||
<a-link v-permission="['routing:routing:detail']" title="详情" @click="onDetail(record)">详情</a-link>
|
||||
<a-link v-permission="['routing:routing:update']" title="修改" @click="onUpdate(record)">修改</a-link>
|
||||
<a-link
|
||||
v-permission="['routing:routing:delete']"
|
||||
status="danger"
|
||||
:disabled="record.disabled"
|
||||
:title="record.disabled ? '不可删除' : '删除'"
|
||||
@click="onDelete(record)"
|
||||
>
|
||||
删除
|
||||
</a-link>
|
||||
</a-space>
|
||||
</template>
|
||||
</GiTable>
|
||||
|
||||
<RoutingAddModal ref="RoutingAddModalRef" @save-success="search" />
|
||||
<RoutingDetailDrawer ref="RoutingDetailDrawerRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import RoutingAddModal from './RoutingAddModal.vue'
|
||||
import RoutingDetailDrawer from './RoutingDetailDrawer.vue'
|
||||
import { type RoutingResp, type RoutingQuery, deleteRouting, exportRouting, listRouting } from '@/apis/routing/routing'
|
||||
import type { TableInstanceColumns } from '@/components/GiTable/type'
|
||||
import { useDownload, useTable } from '@/hooks'
|
||||
import { isMobile } from '@/utils'
|
||||
import has from '@/utils/has'
|
||||
import { useDict } from "@/hooks/app";
|
||||
import GiCellTag from '@/components/GiCell/GiCellTag.vue'
|
||||
|
||||
defineOptions({ name: 'Routing' })
|
||||
|
||||
const { yse_or_no, process_status } = useDict('yse_or_no', 'process_status')
|
||||
|
||||
const queryForm = reactive<RoutingQuery>({
|
||||
routingCode: undefined,
|
||||
routingName: undefined,
|
||||
version: undefined,
|
||||
isActive: undefined,
|
||||
status: undefined,
|
||||
sort: ['id,desc']
|
||||
})
|
||||
|
||||
const {
|
||||
tableData: dataList,
|
||||
loading,
|
||||
pagination,
|
||||
search,
|
||||
handleDelete
|
||||
} = useTable((page) => listRouting({ ...queryForm, ...page }), { immediate: true })
|
||||
const columns = ref<TableInstanceColumns[]>([
|
||||
{ title: '工艺路线编码', dataIndex: 'routingCode', slotName: 'routingCode' },
|
||||
{ title: '工艺路线名称', dataIndex: 'routingName', slotName: 'routingName' },
|
||||
{ title: '产品', dataIndex: 'productId', slotName: 'productId' },
|
||||
{ title: '产线', dataIndex: 'lineId', slotName: 'lineId' },
|
||||
{ title: '版本号', dataIndex: 'version', slotName: 'version' },
|
||||
{ title: '是否启用', dataIndex: 'isActive', slotName: 'isActive', align: 'center' },
|
||||
{ title: '状态', dataIndex: 'status', slotName: 'status', align: 'center' },
|
||||
{ title: '备注', dataIndex: 'remark', slotName: 'remark' },
|
||||
{ title: '创建人', dataIndex: 'createUserString', slotName: 'createUser', show: false },
|
||||
{ title: '创建时间', dataIndex: 'createTime', slotName: 'createTime', show: false },
|
||||
{ title: '修改人', dataIndex: 'updateUserString', slotName: 'updateUser', show: false },
|
||||
{ title: '修改时间', dataIndex: 'updateTime', slotName: 'updateTime', show: false },
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
slotName: 'action',
|
||||
width: 160,
|
||||
align: 'center',
|
||||
fixed: !isMobile() ? 'right' : undefined,
|
||||
show: has.hasPermOr(['routing:routing:detail', 'routing:routing:update', 'routing:routing:delete'])
|
||||
}
|
||||
]);
|
||||
|
||||
// 重置
|
||||
const reset = () => {
|
||||
queryForm.routingCode = undefined
|
||||
queryForm.routingName = undefined
|
||||
queryForm.version = undefined
|
||||
queryForm.isActive = undefined
|
||||
queryForm.status = undefined
|
||||
search()
|
||||
}
|
||||
|
||||
// 删除
|
||||
const onDelete = (record: RoutingResp) => {
|
||||
return handleDelete(() => deleteRouting(record.id), {
|
||||
content: `是否确定删除该条数据?`,
|
||||
showModal: true
|
||||
})
|
||||
}
|
||||
|
||||
// 导出
|
||||
const onExport = () => {
|
||||
useDownload(() => exportRouting(queryForm))
|
||||
}
|
||||
|
||||
const RoutingAddModalRef = ref<InstanceType<typeof RoutingAddModal>>()
|
||||
// 新增
|
||||
const onAdd = () => {
|
||||
RoutingAddModalRef.value?.onAdd()
|
||||
}
|
||||
|
||||
// 修改
|
||||
const onUpdate = (record: RoutingResp) => {
|
||||
RoutingAddModalRef.value?.onUpdate(record.id)
|
||||
}
|
||||
|
||||
const RoutingDetailDrawerRef = ref<InstanceType<typeof RoutingDetailDrawer>>()
|
||||
// 详情
|
||||
const onDetail = (record: RoutingResp) => {
|
||||
RoutingDetailDrawerRef.value?.onOpen(record.id)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
Reference in New Issue
Block a user