feat:任务制单-添加任务单名称/客户

main
黄伟杰 5 days ago
parent d07354c9a5
commit 95453a6436

@ -4,6 +4,9 @@ import request from '@/config/axios'
export interface TaskVO {
id: number // ID
code: string // 编码
taskName: string // 任务单名称
customerId: string // 客户ID
customerName?: string // 客户名称
orderDate: Date // 下达日期
deliveryDate: Date // 交货日期
isUrgent: string // 是否急单0-否 1-是

@ -7,33 +7,49 @@
label-width="120px"
v-loading="formLoading"
>
<el-form-item prop="code">
<template #label>
<span>
{{ t('ProductionPlan.Task.dialogCodeLabel') }}
<el-tooltip :content="t('ProductionPlan.Task.dialogCodeTooltip')" placement="top">
<Icon icon="ep:question-filled" />
</el-tooltip>
</span>
</template>
<el-row :gutter="10" style="width: 100%;">
<el-col :xs="24" :sm="18" :md="16" :lg="14" :xl="12">
<el-input
:disabled="formData.isCode == true || formType === 'update'"
v-model="formData.code"
:placeholder="t('ProductionPlan.Task.dialogCodePlaceholder')"
/>
</el-col>
<el-col :xs="24" :sm="6" :md="4" :lg="3" :xl="2">
<div>
<el-switch
v-model="formData.isCode"
:disabled="formType === 'update'"
<template #label>
<span>
{{ t('ProductionPlan.Task.dialogCodeLabel') }}
<el-tooltip :content="t('ProductionPlan.Task.dialogCodeTooltip')" placement="top">
<Icon icon="ep:question-filled" />
</el-tooltip>
</span>
</template>
<div class="task-code-field">
<el-input
:disabled="formData.isCode == true || formType === 'update'"
v-model="formData.code"
:placeholder="t('ProductionPlan.Task.dialogCodePlaceholder')"
/>
<el-switch v-model="formData.isCode" :disabled="formType === 'update'" />
</div>
</el-form-item>
<el-form-item :label="t('ProductionPlan.Task.dialogTaskNameLabel')" prop="taskName">
<el-input
v-model="formData.taskName"
:placeholder="t('ProductionPlan.Task.dialogTaskNamePlaceholder')"
/>
</div>
</el-col>
</el-row>
</el-form-item>
</el-form-item>
<el-form-item :label="t('ProductionPlan.Task.dialogCustomerLabel')" prop="customerId">
<el-input
:model-value="formData.customerName"
readonly
clearable
:placeholder="t('ProductionPlan.Task.dialogCustomerPlaceholder')"
@clear="clearCustomer"
@click="openCustomerDialog"
>
<template #append>
<el-button @click.stop="openCustomerDialog">
<Icon icon="ep:search" />
</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item :label="t('ProductionPlan.Task.dialogDeliveryDateLabel')" prop="deliveryDate">
<el-date-picker
v-model="formData.deliveryDate"
@ -44,14 +60,15 @@
class="!w-full"
/>
</el-form-item>
<el-form-item :label="t('ProductionPlan.Task.dialogTaskTypeLabel')" prop="taskType">
<template #label>
<span>
{{ t('ProductionPlan.Task.dialogTaskTypeLabel') }}
<el-tooltip :content="t('ProductionPlan.Task.dialogTaskTypeTooltip')" placement="top">
<Icon icon="ep:question-filled" />
</el-tooltip>
</span>
<span>
{{ t('ProductionPlan.Task.dialogTaskTypeLabel') }}
<el-tooltip :content="t('ProductionPlan.Task.dialogTaskTypeTooltip')" placement="top">
<Icon icon="ep:question-filled" />
</el-tooltip>
</span>
</template>
<el-radio-group v-model="formData.taskType">
<el-radio
@ -63,6 +80,7 @@
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="t('ProductionPlan.Task.dialogIsUrgentLabel')" prop="isUrgent">
<el-radio-group v-model="formData.isUrgent">
<el-radio label="0">{{ t('ProductionPlan.Task.urgentNoLabel') }}</el-radio>
@ -71,19 +89,127 @@
</el-form-item>
<el-form-item :label="t('ProductionPlan.Task.dialogRemarkLabel')" prop="remark">
<el-input v-model="formData.remark" :placeholder="t('ProductionPlan.Task.dialogRemarkPlaceholder')" type="textarea"/>
<el-input
v-model="formData.remark"
:placeholder="t('ProductionPlan.Task.dialogRemarkPlaceholder')"
type="textarea"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('ProductionPlan.Task.dialogSubmitButtonText') }}</el-button>
<el-button @click="dialogVisible = false">{{ t('ProductionPlan.Task.dialogCancelButtonText') }}</el-button>
<el-button @click="submitForm" type="primary" :disabled="formLoading">
{{ t('ProductionPlan.Task.dialogSubmitButtonText') }}
</el-button>
<el-button @click="dialogVisible = false">
{{ t('ProductionPlan.Task.dialogCancelButtonText') }}
</el-button>
</template>
</Dialog>
<el-dialog
v-model="customerDialogVisible"
:title="t('ProductionPlan.Task.selectCustomerDialogTitle')"
width="1100px"
append-to-body
class="task-customer-dialog"
>
<el-form
ref="customerQueryFormRef"
:model="customerQueryParams"
:inline="true"
class="-mb-15px"
label-width="88px"
>
<el-form-item :label="t('MesCustomer.fields.name')" prop="name">
<el-input
v-model="customerQueryParams.name"
clearable
class="!w-220px"
:placeholder="t('MesCustomer.placeholders.name')"
@keyup.enter="handleCustomerQuery"
/>
</el-form-item>
<el-form-item :label="t('MesCustomer.fields.mobile')" prop="mobile">
<el-input
v-model="customerQueryParams.mobile"
clearable
class="!w-220px"
:placeholder="t('MesCustomer.placeholders.mobile')"
@keyup.enter="handleCustomerQuery"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleCustomerQuery">
<Icon icon="ep:search" class="mr-5px" />{{ t('common.query') }}
</el-button>
<el-button @click="resetCustomerQuery">
<Icon icon="ep:refresh" class="mr-5px" />{{ t('common.reset') }}
</el-button>
</el-form-item>
</el-form>
<ContentWrap>
<el-table
v-loading="customerLoading"
:data="customerList"
:show-overflow-tooltip="true"
:stripe="true"
highlight-current-row
row-key="id"
@current-change="handleCustomerCurrentChange"
@row-dblclick="selectCustomer"
>
<el-table-column width="55" align="center">
<template #default="scope">
<el-radio :model-value="customerCurrentRow?.id" :label="scope.row.id" @change="handleCustomerCurrentChange(scope.row)" @click.stop>
<span></span>
</el-radio>
</template>
</el-table-column>
<el-table-column align="center" :label="t('MesCustomer.fields.name')" prop="name" width="160" />
<el-table-column align="center" :label="t('MesCustomer.fields.customerCode')" prop="customerCode" width="140" />
<el-table-column align="center" :label="t('MesCustomer.fields.contactName')" prop="contactName" width="120" />
<el-table-column align="center" :label="t('MesCustomer.fields.source')" prop="source" width="110">
<template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="scope.row.source" />
</template>
</el-table-column>
<el-table-column align="center" :label="t('MesCustomer.fields.mobile')" prop="mobile" width="130" />
<el-table-column align="center" :label="t('MesCustomer.fields.telephone')" prop="telephone" width="130" />
<el-table-column align="center" :label="t('MesCustomer.fields.email')" prop="email" width="180" />
<el-table-column align="center" :label="t('MesCustomer.fields.level')" prop="level" width="135">
<template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" />
</template>
</el-table-column>
<el-table-column align="center" :label="t('MesCustomer.fields.ownerUser')" prop="ownerUserName" width="120" />
</el-table>
<div class="task-customer-dialog__pagination">
<Pagination
v-model:limit="customerQueryParams.pageSize"
v-model:page="customerQueryParams.pageNo"
:total="customerTotal"
@pagination="getCustomerList"
/>
</div>
</ContentWrap>
<template #footer>
<div class="task-customer-dialog__footer">
<el-button @click="customerDialogVisible = false">
{{ t('common.cancel') }}
</el-button>
<el-button type="primary" @click="confirmCustomer">
{{ t('common.ok') }}
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import {DICT_TYPE, getStrDictOptions} from '@/utils/dict'
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
import { TaskApi, TaskVO } from '@/api/mes/task'
import * as CustomerApi from '@/api/mes/customer'
/** 生产任务单 表单 */
defineOptions({ name: 'TaskForm' })
@ -91,12 +217,32 @@ defineOptions({ name: 'TaskForm' })
const { t } = useI18n() //
const message = useMessage() //
type TaskFormData = {
id?: number
taskName?: string
customerId?: string
customerName?: string
code?: string
orderDate?: string | number | Date
deliveryDate?: string | number | Date
status?: number
taskType?: string
isUrgent?: string
processInstanceId?: string
remark?: string
isEnable?: boolean
isCode?: boolean
}
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
const formData = ref<TaskFormData>({
id: undefined,
taskName: undefined,
customerId: undefined,
customerName: undefined,
code: undefined,
orderDate: undefined,
deliveryDate: undefined,
@ -108,6 +254,21 @@ const formData = ref({
isEnable: undefined,
isCode: undefined
})
const customerDialogVisible = ref(false)
const customerLoading = ref(false)
const customerList = ref<CustomerApi.CustomerVO[]>([])
const customerTotal = ref(0)
const customerCurrentRow = ref<CustomerApi.CustomerVO>()
const customerQueryFormRef = ref()
const customerQueryParams = reactive({
pageNo: 1,
pageSize: 10,
name: '',
mobile: '',
pool: undefined
})
const disablePastDate = (date: Date) => {
return date.getTime() < new Date(new Date().setHours(0, 0, 0, 0)).getTime()
}
@ -125,15 +286,95 @@ const validateDeliveryDate = (_rule: any, value: any, callback: (error?: Error)
callback()
}
const formRules = reactive({
taskName: [
{ required: true, message: t('ProductionPlan.Task.validatorTaskNameRequired'), trigger: 'blur' }
],
customerId: [
{ required: true, message: t('ProductionPlan.Task.validatorCustomerRequired'), trigger: 'change' }
],
deliveryDate: [
{ required: true, message: t('ProductionPlan.Task.validatorDeliveryDateRequired'), trigger: 'blur' },
{ validator: validateDeliveryDate, trigger: ['change', 'blur'] }
],
taskType: [{ required: true, message: t('ProductionPlan.Task.validatorTaskTypeRequired'), trigger: 'blur' }],
isUrgent: [{ required: true, message: t('ProductionPlan.Task.validatorIsUrgentRequired'), trigger: 'change' }]
taskType: [
{ required: true, message: t('ProductionPlan.Task.validatorTaskTypeRequired'), trigger: 'blur' }
],
isUrgent: [
{ required: true, message: t('ProductionPlan.Task.validatorIsUrgentRequired'), trigger: 'change' }
]
})
const formRef = ref() // Ref
const getCustomerName = (row?: Partial<CustomerApi.CustomerVO>) => {
return row?.name ?? ''
}
const getCustomerList = async () => {
customerLoading.value = true
try {
const data = await CustomerApi.getCustomerPage(customerQueryParams)
customerList.value = data.list ?? []
customerTotal.value = data.total ?? 0
} finally {
customerLoading.value = false
}
}
const handleCustomerQuery = () => {
customerQueryParams.pageNo = 1
getCustomerList()
}
const resetCustomerQuery = () => {
customerQueryFormRef.value?.resetFields?.()
customerQueryParams.pageNo = 1
customerQueryParams.pageSize = 10
customerQueryParams.name = ''
customerQueryParams.mobile = ''
getCustomerList()
}
const openCustomerDialog = async () => {
customerDialogVisible.value = true
customerCurrentRow.value = undefined
await getCustomerList()
}
const handleCustomerCurrentChange = (row?: CustomerApi.CustomerVO) => {
customerCurrentRow.value = row
}
const selectCustomer = (row: CustomerApi.CustomerVO) => {
customerCurrentRow.value = row
confirmCustomer()
}
const confirmCustomer = () => {
if (!customerCurrentRow.value) {
message.warning(t('ProductionPlan.Task.dialogCustomerPlaceholder'))
return
}
formData.value.customerId = String(customerCurrentRow.value.id)
formData.value.customerName = getCustomerName(customerCurrentRow.value)
formRef.value?.clearValidate('customerId')
customerDialogVisible.value = false
}
const clearCustomer = () => {
formData.value.customerId = undefined
formData.value.customerName = undefined
formRef.value?.clearValidate('customerId')
}
const hydrateCustomerName = async () => {
const customerId = formData.value.customerId
if (!customerId || formData.value.customerName) return
try {
const customer = await CustomerApi.getCustomer(Number(customerId))
formData.value.customerName = getCustomerName(customer)
} catch {}
}
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
@ -147,8 +388,11 @@ const open = async (type: string, id?: number) => {
const taskData = await TaskApi.getTask(id)
formData.value = {
...taskData,
customerId: taskData?.customerId ? String(taskData.customerId) : undefined,
customerName: taskData?.customerName ?? taskData?.customer?.name,
isUrgent: String(taskData?.isUrgent ?? '0')
}
await hydrateCustomerName()
} finally {
formLoading.value = false
}
@ -164,7 +408,8 @@ const submitForm = async () => {
//
formLoading.value = true
try {
const data = formData.value as unknown as TaskVO
const data = { ...(formData.value as any) } as TaskVO & { customerName?: string }
delete data.customerName
if (formType.value === 'create') {
await TaskApi.createTask(data)
message.success(t('common.createSuccess'))
@ -184,6 +429,9 @@ const submitForm = async () => {
const resetForm = () => {
formData.value = {
id: undefined,
taskName: undefined,
customerId: undefined,
customerName: undefined,
code: undefined,
orderDate: undefined,
taskType: '订单任务',
@ -198,3 +446,40 @@ const resetForm = () => {
formRef.value?.resetFields()
}
</script>
<style scoped>
.task-code-field {
display: flex;
align-items: center;
width: 100%;
gap: 20px;
}
.task-code-field :deep(.el-input) {
flex: 1;
}
.task-code-field :deep(.el-switch) {
flex: 0 0 auto;
}
.task-customer-dialog :deep(.el-dialog__body) {
padding-top: 12px;
}
.task-customer-dialog__pagination {
display: flex;
justify-content: flex-end;
padding-top: 12px;
}
.task-customer-dialog__footer {
display: flex;
justify-content: flex-end;
gap: 12px;
}
.task-customer-dialog :deep(.el-radio__label) {
display: none;
}
</style>

@ -117,6 +117,8 @@
@current-change="handleCurrentChange"
>
<el-table-column :label="t('ProductionPlan.Task.tableCodeColumn')" align="center" prop="code" sortable/>
<el-table-column :label="t('ProductionPlan.Task.tableTaskNameColumn')" align="center" prop="taskName" min-width="140" sortable />
<el-table-column :label="t('ProductionPlan.Task.tableCustomerNameColumn')" align="center" prop="customerName" min-width="140" sortable />
<el-table-column :label="t('ProductionPlan.Task.tableOrderDateColumn')" align="center" prop="orderDate" :formatter="dateFormatter2" sortable/>
<el-table-column :label="t('ProductionPlan.Task.tableDeliveryDateColumn')" align="center" prop="deliveryDate" :formatter="dateFormatter2" sortable/>
<el-table-column :label="t('ProductionPlan.Task.tableTaskTypeColumn')" align="center" prop="taskType" sortable>

Loading…
Cancel
Save