修复发布任务失败问题并添加编码自动生成功能

1. 修复task表approval_status字段长度问题(VARCHAR(20)->VARCHAR(50))
2. 为品牌、平台、类目、任务子类型添加自动生成编码功能
3. 优化编码输入体验,添加自动生成按钮
This commit is contained in:
Your Name 2026-01-02 18:28:41 +08:00
parent e3ff05e2b5
commit e978a7cdb1
3 changed files with 141 additions and 4 deletions

View File

@ -0,0 +1,36 @@
-- 修复 task 表的 approval_status 字段长度问题
-- 问题:approval_status 字段长度为 VARCHAR(20),但实际值 'pending_demand_approval' 有 23 个字符
-- 错误:Data truncation: Data too long for column 'approval_status'
-- 解决:将字段长度扩大到 VARCHAR(50)
-- 日期:2026-01-02
USE designhub;
-- 修改 approval_status 字段长度
ALTER TABLE `task`
MODIFY COLUMN `approval_status` VARCHAR(50) DEFAULT 'draft'
COMMENT '审批状态:draft-草稿,pending_demand_approval-待需求部门审批,pending_receiving_approval-待接单部门审批,approved-已通过,rejected-已拒绝';
-- 验证修改结果
SELECT
COLUMN_NAME,
COLUMN_TYPE,
COLUMN_DEFAULT,
COLUMN_COMMENT
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = 'designhub'
AND TABLE_NAME = 'task'
AND COLUMN_NAME = 'approval_status';
-- 说明:
-- 审批状态值说明:
-- 1. draft - 草稿(默认值)
-- 2. pending_demand_approval - 待需求部门负责人审批(23字符)
-- 3. pending_receiving_approval - 待接单部门主管审批(28字符)
-- 4. approved - 已通过
-- 5. rejected - 已拒绝
--
-- VARCHAR(50) 足以容纳所有可能的状态值

View File

@ -11,6 +11,7 @@ declare module 'vue' {
ABadge: typeof import('ant-design-vue/es')['Badge'] ABadge: typeof import('ant-design-vue/es')['Badge']
AButton: typeof import('ant-design-vue/es')['Button'] AButton: typeof import('ant-design-vue/es')['Button']
ACalendar: typeof import('ant-design-vue/es')['Calendar'] ACalendar: typeof import('ant-design-vue/es')['Calendar']
ACard: typeof import('ant-design-vue/es')['Card']
ACheckbox: typeof import('ant-design-vue/es')['Checkbox'] ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup'] ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
ACol: typeof import('ant-design-vue/es')['Col'] ACol: typeof import('ant-design-vue/es')['Col']

View File

@ -958,7 +958,13 @@
<a-input v-model:value="formData.taskSubType.name" placeholder="请输入子类型名称(如:新品、优化)" /> <a-input v-model:value="formData.taskSubType.name" placeholder="请输入子类型名称(如:新品、优化)" />
</a-form-item> </a-form-item>
<a-form-item label="子类型编码" required> <a-form-item label="子类型编码" required>
<a-input v-model:value="formData.taskSubType.code" placeholder="请输入子类型编码(如:new_product)" /> <a-input v-model:value="formData.taskSubType.code" placeholder="留空自动生成">
<template #addonAfter>
<a-button size="small" type="link" @click="autoGenerateTaskSubTypeCode" style="padding: 0 8px;">
自动生成
</a-button>
</template>
</a-input>
</a-form-item> </a-form-item>
<a-form-item label="描述"> <a-form-item label="描述">
<a-textarea v-model:value="formData.taskSubType.description" :rows="3" placeholder="请输入描述" /> <a-textarea v-model:value="formData.taskSubType.description" :rows="3" placeholder="请输入描述" />
@ -987,7 +993,13 @@
<a-input v-model:value="formData.brand.name" placeholder="请输入品牌名称" /> <a-input v-model:value="formData.brand.name" placeholder="请输入品牌名称" />
</a-form-item> </a-form-item>
<a-form-item label="品牌编码"> <a-form-item label="品牌编码">
<a-input v-model:value="formData.brand.brandCode" placeholder="请输入品牌编码" /> <a-input v-model:value="formData.brand.brandCode" placeholder="留空自动生成">
<template #addonAfter>
<a-button size="small" type="link" @click="autoGenerateBrandCode" style="padding: 0 8px;">
自动生成
</a-button>
</template>
</a-input>
</a-form-item> </a-form-item>
<a-form-item label="品牌描述"> <a-form-item label="品牌描述">
<a-textarea v-model:value="formData.brand.description" :rows="3" placeholder="请输入描述" /> <a-textarea v-model:value="formData.brand.description" :rows="3" placeholder="请输入描述" />
@ -1015,7 +1027,13 @@
<a-input v-model:value="formData.platform.name" placeholder="请输入平台名称" /> <a-input v-model:value="formData.platform.name" placeholder="请输入平台名称" />
</a-form-item> </a-form-item>
<a-form-item label="平台编码"> <a-form-item label="平台编码">
<a-input v-model:value="formData.platform.platformCode" placeholder="请输入平台编码" /> <a-input v-model:value="formData.platform.platformCode" placeholder="留空自动生成">
<template #addonAfter>
<a-button size="small" type="link" @click="autoGeneratePlatformCode" style="padding: 0 8px;">
自动生成
</a-button>
</template>
</a-input>
</a-form-item> </a-form-item>
<a-form-item label="平台描述"> <a-form-item label="平台描述">
<a-textarea v-model:value="formData.platform.description" :rows="3" placeholder="请输入描述" /> <a-textarea v-model:value="formData.platform.description" :rows="3" placeholder="请输入描述" />
@ -1043,7 +1061,13 @@
<a-input v-model:value="formData.category.name" placeholder="请输入类目名称" /> <a-input v-model:value="formData.category.name" placeholder="请输入类目名称" />
</a-form-item> </a-form-item>
<a-form-item label="类目编码"> <a-form-item label="类目编码">
<a-input v-model:value="formData.category.categoryCode" placeholder="请输入类目编码" /> <a-input v-model:value="formData.category.categoryCode" placeholder="留空自动生成">
<template #addonAfter>
<a-button size="small" type="link" @click="autoGenerateCategoryCode" style="padding: 0 8px;">
自动生成
</a-button>
</template>
</a-input>
</a-form-item> </a-form-item>
<a-form-item label="类目描述"> <a-form-item label="类目描述">
<a-textarea v-model:value="formData.category.description" :rows="3" placeholder="请输入描述" /> <a-textarea v-model:value="formData.category.description" :rows="3" placeholder="请输入描述" />
@ -1881,6 +1905,82 @@ const handleScoreAdjust = async () => {
} }
} }
// 自动生成编码的辅助函数
const generateCode = (name: string, prefix: string = ''): string => {
if (!name) return ''
// 移除特殊字符,只保留字母、数字和汉字
const cleanName = name.replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, '')
let code = ''
// 尝试提取英文字母
const englishChars = cleanName.match(/[a-zA-Z]+/g)
if (englishChars && englishChars.length > 0) {
code = englishChars.join('').toUpperCase().substring(0, 8)
}
// 如果没有英文字母,使用时间戳后6位
if (!code) {
code = 'CODE' + Date.now().toString().slice(-6)
}
// 添加前缀
if (prefix) {
code = prefix.toUpperCase() + '_' + code
}
return code
}
// 自动生成品牌编码
const autoGenerateBrandCode = () => {
if (!formData.brand.name) {
message.warning('请先输入品牌名称')
return
}
formData.brand.brandCode = generateCode(formData.brand.name, 'BR')
}
// 自动生成平台编码
const autoGeneratePlatformCode = () => {
if (!formData.platform.name) {
message.warning('请先输入平台名称')
return
}
formData.platform.platformCode = generateCode(formData.platform.name, 'PF')
}
// 自动生成类目编码
const autoGenerateCategoryCode = () => {
if (!formData.category.name) {
message.warning('请先输入类目名称')
return
}
formData.category.categoryCode = generateCode(formData.category.name, 'CAT')
}
// 自动生成任务子类型编码
const autoGenerateTaskSubTypeCode = () => {
if (!formData.taskSubType.name) {
message.warning('请先输入子类型名称')
return
}
// 任务子类型编码使用小写加下划线格式
let code = formData.taskSubType.name
.toLowerCase()
.replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, '_')
.replace(/_{2,}/g, '_')
.replace(/^_|_$/g, '')
// 如果是中文,简化处理
if (/[\u4e00-\u9fa5]/.test(code)) {
code = 'subtype_' + Date.now().toString().slice(-6)
}
formData.taskSubType.code = code
}
// 显示弹窗 // 显示弹窗
const showDemandTypeModal = async (item?: DemandType) => { const showDemandTypeModal = async (item?: DemandType) => {
editingItem.value = item editingItem.value = item