first commit
This commit is contained in:
273
src/views/erp/purchase/evaluation/SupplierEvaluationForm.vue
Normal file
273
src/views/erp/purchase/evaluation/SupplierEvaluationForm.vue
Normal file
@@ -0,0 +1,273 @@
|
||||
<template>
|
||||
<Dialog v-model="dialogVisible" :title="dialogTitle" width="100%" fullscreen class="mobile-eval-form-dialog">
|
||||
<div class="mobile-form-wrapper" v-loading="formLoading">
|
||||
<el-form ref="formRef" :model="formData" :rules="formRules" label-position="top">
|
||||
<div class="mobile-form-section">
|
||||
<div class="mobile-form-section__title">基本信息</div>
|
||||
<el-form-item label="供应商" prop="supplierName">
|
||||
<el-input v-model="formData.supplierName" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="订单单号" prop="orderNo">
|
||||
<el-input v-model="formData.orderNo" disabled />
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div class="mobile-form-section">
|
||||
<div class="mobile-form-section__title">评分标准(满分10分)</div>
|
||||
<el-form-item label="质量评分" prop="qualityScore">
|
||||
<div class="rating-container">
|
||||
<el-rate v-model="formData.qualityScore" :max="10" show-score score-template="{value}分" allow-half />
|
||||
<div class="rating-desc">产品质量、规格符合度、缺陷率等</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="服务评分" prop="serviceScore">
|
||||
<div class="rating-container">
|
||||
<el-rate v-model="formData.serviceScore" :max="10" show-score score-template="{value}分" allow-half />
|
||||
<div class="rating-desc">售前售后服务、响应速度、专业程度等</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="价格评分" prop="priceScore">
|
||||
<div class="rating-container">
|
||||
<el-rate v-model="formData.priceScore" :max="10" show-score score-template="{value}分" allow-half />
|
||||
<div class="rating-desc">价格合理性、性价比、优惠政策等</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="交付评分" prop="deliveryScore">
|
||||
<div class="rating-container">
|
||||
<el-rate v-model="formData.deliveryScore" :max="10" show-score score-template="{value}分" allow-half />
|
||||
<div class="rating-desc">交付及时性、包装质量、物流配送等</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div class="mobile-form-section">
|
||||
<div class="mobile-form-section__title">综合评分</div>
|
||||
<div class="total-score">
|
||||
<span class="score-value">{{ totalScore.toFixed(1) }}分</span>
|
||||
<span class="score-level">{{ getScoreLevel(totalScore) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mobile-form-section">
|
||||
<div class="mobile-form-section__title">评价备注</div>
|
||||
<el-form-item prop="remark">
|
||||
<el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="请输入评价备注(可选)" maxlength="500" show-word-limit />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="mobile-form-footer">
|
||||
<el-button @click="dialogVisible = false" style="flex:1">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm" :loading="formLoading" style="flex:1">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SupplierEvaluationApi, SupplierEvaluationVO } from '@/api/erp/purchase/supplierEvaluation'
|
||||
|
||||
interface SupplierEvaluationForm {
|
||||
id?: number
|
||||
supplierId: number
|
||||
supplierName: string
|
||||
purchaseOrderId: number
|
||||
orderNo: string
|
||||
qualityScore: number
|
||||
serviceScore: number
|
||||
priceScore: number
|
||||
deliveryScore: number
|
||||
remark: string
|
||||
}
|
||||
|
||||
const { t } = useI18n()
|
||||
const message = useMessage()
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const formLoading = ref(false)
|
||||
const formType = ref('')
|
||||
const formRef = ref()
|
||||
const formData = ref<SupplierEvaluationForm>({
|
||||
supplierId: 0,
|
||||
supplierName: '',
|
||||
purchaseOrderId: 0,
|
||||
orderNo: '',
|
||||
qualityScore: 5,
|
||||
serviceScore: 5,
|
||||
priceScore: 5,
|
||||
deliveryScore: 5,
|
||||
remark: ''
|
||||
})
|
||||
|
||||
const formRules = reactive({
|
||||
qualityScore: [{ required: true, message: '请评价质量分数', trigger: 'change' }],
|
||||
serviceScore: [{ required: true, message: '请评价服务分数', trigger: 'change' }],
|
||||
priceScore: [{ required: true, message: '请评价价格分数', trigger: 'change' }],
|
||||
deliveryScore: [{ required: true, message: '请评价交付分数', trigger: 'change' }]
|
||||
})
|
||||
|
||||
// 计算综合评分
|
||||
const totalScore = computed(() => {
|
||||
return (formData.value.qualityScore + formData.value.serviceScore +
|
||||
formData.value.priceScore + formData.value.deliveryScore) / 4
|
||||
})
|
||||
|
||||
// 获取评分等级
|
||||
const getScoreLevel = (score: number) => {
|
||||
if (score >= 9) return '优秀'
|
||||
if (score >= 8) return '良好'
|
||||
if (score >= 7) return '一般'
|
||||
if (score >= 6) return '及格'
|
||||
return '不及格'
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = type === 'create' ? '新增供应商评价' : '修改供应商评价'
|
||||
formType.value = type
|
||||
resetForm()
|
||||
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = await SupplierEvaluationApi.getSupplierEvaluation(id)
|
||||
formData.value = {
|
||||
...data,
|
||||
supplierName: data.supplierName || '',
|
||||
orderNo: data.orderNo || ''
|
||||
}
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
supplierId: 0,
|
||||
supplierName: '',
|
||||
purchaseOrderId: 0,
|
||||
orderNo: '',
|
||||
qualityScore: 5,
|
||||
serviceScore: 5,
|
||||
priceScore: 5,
|
||||
deliveryScore: 5,
|
||||
remark: ''
|
||||
}
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitForm = async () => {
|
||||
if (!formRef.value) return
|
||||
const valid = await formRef.value.validate()
|
||||
if (!valid) return
|
||||
|
||||
try {
|
||||
formLoading.value = true
|
||||
const data = {
|
||||
...formData.value,
|
||||
totalScore: totalScore.value
|
||||
}
|
||||
|
||||
if (formType.value === 'create') {
|
||||
await SupplierEvaluationApi.createSupplierEvaluation(data)
|
||||
message.success('新增成功')
|
||||
} else {
|
||||
await SupplierEvaluationApi.updateSupplierEvaluation(data)
|
||||
message.success('修改成功')
|
||||
}
|
||||
|
||||
dialogVisible.value = false
|
||||
emit('success')
|
||||
} catch (error) {
|
||||
console.error('操作失败', error)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 定义事件
|
||||
const emit = defineEmits<{
|
||||
success: []
|
||||
}>()
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mobile-form-wrapper {
|
||||
padding: 0 4px;
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
.mobile-form-section {
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 14px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: 0 1px 4px rgba(0,0,0,0.06);
|
||||
&__title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
}
|
||||
.mobile-form-footer {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
.rating-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.rating-desc {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
}
|
||||
.total-score {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.score-value {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #409eff;
|
||||
}
|
||||
.score-level {
|
||||
padding: 4px 12px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
background-color: #f0f9ff;
|
||||
color: #409eff;
|
||||
border: 1px solid #b3d8ff;
|
||||
}
|
||||
:deep(.el-rate) {
|
||||
height: auto;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
:deep(.el-rate__text) {
|
||||
color: #409eff;
|
||||
font-weight: 500;
|
||||
}
|
||||
:deep(.mobile-eval-form-dialog .el-dialog__body) {
|
||||
padding: 12px;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user