225 lines
5.8 KiB
Vue
225 lines
5.8 KiB
Vue
<template>
|
|
<div class="page requirement-add">
|
|
<van-nav-bar title="新增需求工单" left-arrow @click-left="$router.back()" />
|
|
|
|
<van-form @submit="onSubmit">
|
|
<van-cell-group inset>
|
|
<van-field
|
|
v-model="form.requirementCode"
|
|
name="requirementCode"
|
|
label="需求编号"
|
|
placeholder="请输入需求编号"
|
|
:rules="[{ required: true, message: '请输入需求编号' }]"
|
|
required
|
|
/>
|
|
|
|
<van-field
|
|
v-model="form.requirementName"
|
|
name="requirementName"
|
|
label="需求名称"
|
|
placeholder="请输入需求名称"
|
|
:rules="[{ required: true, message: '请输入需求名称' }]"
|
|
required
|
|
/>
|
|
|
|
<van-field
|
|
v-model="form.customerName"
|
|
is-link
|
|
readonly
|
|
name="customer"
|
|
label="关联客户"
|
|
placeholder="请选择客户"
|
|
@click="showCustomerPicker = true"
|
|
/>
|
|
|
|
<van-field
|
|
v-model="form.projectName"
|
|
is-link
|
|
readonly
|
|
name="project"
|
|
label="关联项目"
|
|
placeholder="请选择项目"
|
|
@click="showProjectPicker = true"
|
|
/>
|
|
|
|
<van-field
|
|
v-model="priorityText"
|
|
is-link
|
|
readonly
|
|
name="priority"
|
|
label="优先级"
|
|
placeholder="请选择优先级"
|
|
@click="showPriorityPicker = true"
|
|
/>
|
|
|
|
<van-field
|
|
v-model="form.description"
|
|
name="description"
|
|
label="需求描述"
|
|
type="textarea"
|
|
rows="3"
|
|
autosize
|
|
placeholder="请输入需求描述"
|
|
/>
|
|
</van-cell-group>
|
|
|
|
<div class="submit-btn">
|
|
<van-button round block type="primary" native-type="submit" :loading="submitting">
|
|
提交
|
|
</van-button>
|
|
</div>
|
|
</van-form>
|
|
|
|
<!-- 优先级选择器 -->
|
|
<van-popup v-model:show="showPriorityPicker" position="bottom" round>
|
|
<van-picker
|
|
:columns="priorityOptions"
|
|
@confirm="onPriorityConfirm"
|
|
@cancel="showPriorityPicker = false"
|
|
/>
|
|
</van-popup>
|
|
|
|
<!-- 客户选择器 -->
|
|
<van-popup v-model:show="showCustomerPicker" position="bottom" round>
|
|
<van-picker
|
|
:columns="customerOptions"
|
|
@confirm="onCustomerConfirm"
|
|
@cancel="showCustomerPicker = false"
|
|
/>
|
|
</van-popup>
|
|
|
|
<!-- 项目选择器 -->
|
|
<van-popup v-model:show="showProjectPicker" position="bottom" round>
|
|
<van-picker
|
|
:columns="projectOptions"
|
|
@confirm="onProjectConfirm"
|
|
@cancel="showProjectPicker = false"
|
|
/>
|
|
</van-popup>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted, computed } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { showFailToast, showSuccessToast } from 'vant'
|
|
import { createRequirement, getCustomerList, getProjectList } from '@/api'
|
|
|
|
const router = useRouter()
|
|
const submitting = ref(false)
|
|
const showPriorityPicker = ref(false)
|
|
const showCustomerPicker = ref(false)
|
|
const showProjectPicker = ref(false)
|
|
|
|
const form = ref({
|
|
requirementCode: '',
|
|
requirementName: '',
|
|
customerId: null as number | null,
|
|
customerName: '',
|
|
projectId: null as number | null,
|
|
projectName: '',
|
|
priority: 'medium',
|
|
description: ''
|
|
})
|
|
|
|
const priorityOptions = [
|
|
{ text: '高', value: 'high' },
|
|
{ text: '中', value: 'medium' },
|
|
{ text: '低', value: 'low' }
|
|
]
|
|
|
|
const priorityText = computed(() => {
|
|
const item = priorityOptions.find(p => p.value === form.value.priority)
|
|
return item?.text || ''
|
|
})
|
|
|
|
const customerOptions = ref<{ text: string; value: number }[]>([])
|
|
const projectOptions = ref<{ text: string; value: number }[]>([])
|
|
|
|
const onPriorityConfirm = ({ selectedOptions }: any) => {
|
|
form.value.priority = selectedOptions[0].value
|
|
showPriorityPicker.value = false
|
|
}
|
|
|
|
const onCustomerConfirm = ({ selectedOptions }: any) => {
|
|
form.value.customerId = selectedOptions[0].value
|
|
form.value.customerName = selectedOptions[0].text
|
|
showCustomerPicker.value = false
|
|
}
|
|
|
|
const onProjectConfirm = ({ selectedOptions }: any) => {
|
|
form.value.projectId = selectedOptions[0].value
|
|
form.value.projectName = selectedOptions[0].text
|
|
showProjectPicker.value = false
|
|
}
|
|
|
|
const loadOptions = async () => {
|
|
try {
|
|
const [customerRes, projectRes] = await Promise.all([
|
|
getCustomerList({ pageNum: 1, pageSize: 100 }),
|
|
getProjectList({ pageNum: 1, pageSize: 100 })
|
|
])
|
|
|
|
customerOptions.value = ((customerRes as any).data?.records || []).map((item: any) => ({
|
|
text: item.customerName,
|
|
value: item.customerId
|
|
}))
|
|
|
|
projectOptions.value = ((projectRes as any).data?.records || []).map((item: any) => ({
|
|
text: item.projectName,
|
|
value: item.projectId
|
|
}))
|
|
} catch (e) {
|
|
console.error('加载选项失败', e)
|
|
}
|
|
}
|
|
|
|
const onSubmit = async () => {
|
|
if (!form.value.requirementCode) {
|
|
showFailToast('请输入需求编号')
|
|
return
|
|
}
|
|
if (!form.value.requirementName) {
|
|
showFailToast('请输入需求名称')
|
|
return
|
|
}
|
|
|
|
submitting.value = true
|
|
try {
|
|
await createRequirement({
|
|
requirementCode: form.value.requirementCode,
|
|
requirementName: form.value.requirementName,
|
|
customerId: form.value.customerId,
|
|
projectId: form.value.projectId,
|
|
priority: form.value.priority,
|
|
description: form.value.description
|
|
})
|
|
showSuccessToast('提交成功')
|
|
router.back()
|
|
} catch (e: any) {
|
|
showFailToast(e.message || '提交失败')
|
|
} finally {
|
|
submitting.value = false
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
loadOptions()
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.requirement-add {
|
|
background: #f5f5f5;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.van-cell-group {
|
|
margin: 12px;
|
|
}
|
|
|
|
.submit-btn {
|
|
margin: 24px 16px;
|
|
}
|
|
</style>
|