29 changed files with 715 additions and 118 deletions
|
After Width: | Height: | Size: 1.0 KiB |
@ -1,4 +1,5 @@ |
|||
export default { |
|||
settings: 'settings', |
|||
about: 'about', |
|||
goToClient: 'go to client', |
|||
}; |
|||
|
|||
@ -1,4 +1,5 @@ |
|||
export default { |
|||
settings: '个人设置', |
|||
about: '关于', |
|||
goToClient: '去客户端', |
|||
}; |
|||
|
|||
@ -0,0 +1,165 @@ |
|||
import type { TableColumn } from '@/components/core/dynamic-table'; |
|||
import { stateTypeList } from './data'; |
|||
import { Tag } from 'ant-design-vue'; |
|||
import { DictEnum } from '@/enums/dictEnum'; |
|||
import { getDictionaryByTypeName } from '@/utils/dict'; |
|||
export type TableListItem = API.IssueType; |
|||
export type TableColumnItem = TableColumn<TableListItem>; |
|||
|
|||
// const questionTypeList = await getDictionaryByTypeName(DictEnum.QUESTION_TYPE);
|
|||
|
|||
// 数据项类型
|
|||
// export type ListItemType = typeof tableData[number];
|
|||
// 使用TableColumn<ListItemType> 将会限制dataIndex的类型,但换来的是dataIndex有类型提示
|
|||
export const baseColumns: TableColumnItem[] = [ |
|||
{ |
|||
title: '问题标题', |
|||
align: 'center', |
|||
dataIndex: 'title', |
|||
// sorter: true,
|
|||
width: 150, |
|||
resizable: true, |
|||
formItemProps: { |
|||
defaultValue: '', |
|||
required: false, |
|||
}, |
|||
}, |
|||
{ |
|||
title: '问题描述', |
|||
align: 'center', |
|||
dataIndex: 'description', |
|||
width: 150, |
|||
ellipsis: true, |
|||
resizable: true, |
|||
formItemProps: { |
|||
defaultValue: '', |
|||
required: false, |
|||
}, |
|||
}, |
|||
{ |
|||
title: '标签', |
|||
align: 'center', |
|||
dataIndex: 'tags', |
|||
width: 200, |
|||
hideInSearch: true, |
|||
}, |
|||
// {
|
|||
// title: '问题属性',
|
|||
// align: 'center',
|
|||
// dataIndex: 'attribute',
|
|||
// width: 150,
|
|||
// formItemProps: {
|
|||
// defaultValue: undefined,
|
|||
// required: false,
|
|||
// component: 'Select',
|
|||
// componentProps: {
|
|||
// options: questionTypeList,
|
|||
// },
|
|||
// },
|
|||
// customRender: ({ record }) => {
|
|||
// const label = questionTypeList?.find((e) => e.value === record.attribute)?.label;
|
|||
|
|||
// return <div>{{ label }}</div>;
|
|||
// },
|
|||
// },
|
|||
{ |
|||
title: '问题号', |
|||
align: 'center', |
|||
dataIndex: 'billcode', |
|||
width: 200, |
|||
formItemProps: { |
|||
defaultValue: '', |
|||
required: false, |
|||
}, |
|||
}, |
|||
{ |
|||
title: '客户', |
|||
align: 'center', |
|||
dataIndex: 'customer', |
|||
width: 150, |
|||
hideInSearch: true, |
|||
formItemProps: { |
|||
defaultValue: '', |
|||
required: false, |
|||
}, |
|||
}, |
|||
{ |
|||
title: '产品', |
|||
align: 'center', |
|||
dataIndex: 'product', |
|||
width: 150, |
|||
hideInSearch: true, |
|||
formItemProps: { |
|||
defaultValue: '', |
|||
required: false, |
|||
}, |
|||
}, |
|||
{ |
|||
title: '版本', |
|||
align: 'center', |
|||
dataIndex: 'version', |
|||
width: 150, |
|||
hideInSearch: true, |
|||
formItemProps: { |
|||
defaultValue: '', |
|||
required: false, |
|||
}, |
|||
}, |
|||
{ |
|||
title: '代理商', |
|||
align: 'center', |
|||
dataIndex: 'agent', |
|||
width: 150, |
|||
hideInSearch: true, |
|||
formItemProps: { |
|||
defaultValue: '', |
|||
required: false, |
|||
}, |
|||
}, |
|||
{ |
|||
title: '服务号', |
|||
align: 'center', |
|||
dataIndex: 'serviceNumber', |
|||
width: 150, |
|||
hideInSearch: true, |
|||
formItemProps: { |
|||
defaultValue: '', |
|||
required: false, |
|||
}, |
|||
}, |
|||
{ |
|||
title: '创建时间', |
|||
align: 'center', |
|||
width: 200, |
|||
dataIndex: 'createTime', |
|||
formItemProps: { |
|||
defaultValue: '', |
|||
required: false, |
|||
component: 'RangePicker', |
|||
componentProps: { |
|||
valueFormat: 'YYYY-MM-DD', |
|||
}, |
|||
}, |
|||
}, |
|||
// state 问题状态
|
|||
{ |
|||
title: '问题状态', |
|||
align: 'center', |
|||
dataIndex: 'state', |
|||
width: 150, |
|||
fixed: 'right', |
|||
formItemProps: { |
|||
defaultValue: undefined, |
|||
required: false, |
|||
component: 'Select', |
|||
componentProps: { |
|||
options: stateTypeList, |
|||
}, |
|||
}, |
|||
customRender: ({ record }) => { |
|||
const { label, color } = stateTypeList.find((e) => e.value === record.state); |
|||
|
|||
return <Tag color={color}>{label}</Tag>; |
|||
}, |
|||
}, |
|||
]; |
|||
@ -0,0 +1,32 @@ |
|||
export const stateTypeList: any = [ |
|||
// Init(0,"待处理"),
|
|||
// Back(1,"退回"),
|
|||
// Develop(2,"开发中"),
|
|||
// Test(3,"测试中"),
|
|||
// End(4,"结束"),
|
|||
{ |
|||
label: '待处理', |
|||
value: 0, |
|||
color: '#f50', |
|||
}, |
|||
{ |
|||
label: '退回', |
|||
value: 1, |
|||
color: '#2db7f5', |
|||
}, |
|||
{ |
|||
label: '开发中', |
|||
value: 2, |
|||
color: '#87d068', |
|||
}, |
|||
{ |
|||
label: '测试中', |
|||
value: 3, |
|||
color: '#108ee9', |
|||
}, |
|||
{ |
|||
label: '已解决', |
|||
value: 4, |
|||
color: '#f50', |
|||
}, |
|||
]; |
|||
@ -0,0 +1,294 @@ |
|||
import type { FormSchema } from '@/components/core/schema-form/'; |
|||
import { TableListItem } from './columns'; |
|||
import { commonUpload } from '@/api/upload'; |
|||
import { message, Button } from 'ant-design-vue'; |
|||
import { getFileExtension } from '@/utils/fileUtils'; |
|||
import { UploadOutlined } from '@ant-design/icons-vue'; |
|||
import { stateTypeList } from './data'; |
|||
import { DictEnum } from '@/enums/dictEnum'; |
|||
import { getDictionaryByTypeName } from '@/utils/dict'; |
|||
import { fetchProdList, fetchVersionPageList } from '@/api/prodVersion'; |
|||
import { vShow } from 'vue'; |
|||
const questionTypeList = await getDictionaryByTypeName(DictEnum.QUESTION_TYPE); |
|||
// 编辑页字段
|
|||
export const getEditFormSchema: ( |
|||
row?: Partial<TableListItem>, |
|||
isDetail?: boolean, |
|||
) => FormSchema[] = (record = {}, isDetail = false) => { |
|||
console.log('questionTypeList: ', questionTypeList); |
|||
|
|||
return [ |
|||
{ |
|||
field: 'billcode', |
|||
component: 'Input', |
|||
label: '问题号', |
|||
dynamicDisabled: true, |
|||
colProps: { |
|||
span: 24, |
|||
}, |
|||
}, |
|||
{ |
|||
field: 'title', |
|||
component: 'Input', |
|||
componentProps: { |
|||
showCount: true, |
|||
maxlength: 150, |
|||
}, |
|||
label: '问题标题', |
|||
colProps: { |
|||
span: 12, |
|||
}, |
|||
rules: [{ required: true }], |
|||
}, |
|||
{ |
|||
field: 'tags', |
|||
component: 'Select', |
|||
componentProps: { |
|||
request: async () => { |
|||
const data = await getDictionaryByTypeName(DictEnum.TAG_TYPE); |
|||
return data; |
|||
}, |
|||
multiple: true, |
|||
placeholder: '请选择标签', |
|||
mode: 'tags', |
|||
allowClear: true, |
|||
}, |
|||
label: '标签', |
|||
colProps: { |
|||
span: 12, |
|||
}, |
|||
rules: [{ required: true, type: 'array' }], |
|||
}, |
|||
// {
|
|||
// label: '问题属性',
|
|||
// field: 'arrtibute',
|
|||
// component: 'Select',
|
|||
// componentProps: {
|
|||
// options: questionTypeList,
|
|||
// },
|
|||
// colProps: {
|
|||
// span: 12,
|
|||
// },
|
|||
// rules: [{ required: true, type: 'string' }],
|
|||
// },
|
|||
|
|||
{ |
|||
field: 'customer', |
|||
component: 'Input', |
|||
label: '客户', |
|||
colProps: { |
|||
span: 12, |
|||
}, |
|||
}, |
|||
{ |
|||
field: 'productId', |
|||
component: 'Select', |
|||
componentProps: ({ formModel, formInstance }) => { |
|||
return { |
|||
request: async () => { |
|||
const data = (await fetchProdList({})) as any; |
|||
return data.map((e) => { |
|||
return { |
|||
label: e.name, |
|||
value: e.id, |
|||
}; |
|||
}); |
|||
}, |
|||
onChange: async (e) => { |
|||
console.log('e: ', e); |
|||
const { data } = await fetchVersionPageList({ |
|||
productId: e, |
|||
current: 1, |
|||
size: 999, |
|||
}); |
|||
if (data && Array.isArray(data) && data.length) { |
|||
formInstance?.setFieldsValue({ |
|||
versionId: data[0].id, |
|||
}); |
|||
formInstance.updateSchema({ |
|||
field: 'versionId', |
|||
componentProps: { |
|||
options: data.map((e) => { |
|||
return { |
|||
label: e.name, |
|||
value: e.id, |
|||
}; |
|||
}), |
|||
}, |
|||
}); |
|||
} |
|||
}, |
|||
}; |
|||
}, |
|||
label: '产品', |
|||
colProps: { |
|||
span: 12, |
|||
}, |
|||
rules: [{ required: true, type: 'number' }], |
|||
}, |
|||
{ |
|||
field: 'versionId', |
|||
component: 'Select', |
|||
componentProps: { |
|||
options: [], |
|||
}, |
|||
label: '版本', |
|||
colProps: { |
|||
span: 12, |
|||
}, |
|||
rules: [{ required: true, type: 'number' }], |
|||
}, |
|||
{ |
|||
field: 'agent', |
|||
component: 'Input', |
|||
label: '代理商', |
|||
colProps: { |
|||
span: 12, |
|||
}, |
|||
}, |
|||
|
|||
{ |
|||
field: 'serviceNumber', |
|||
component: 'Input', |
|||
label: '服务号', |
|||
colProps: { |
|||
span: 12, |
|||
}, |
|||
}, |
|||
|
|||
{ |
|||
field: 'contacts', |
|||
component: 'Input', |
|||
label: '联系人', |
|||
colProps: { |
|||
span: 12, |
|||
}, |
|||
rules: [{ required: true, type: 'string' }], |
|||
}, |
|||
{ |
|||
field: 'contactsEmail', |
|||
component: 'Input', |
|||
label: '联系人邮箱', |
|||
colProps: { |
|||
span: 12, |
|||
}, |
|||
rules: [{ required: true, type: 'string' }], |
|||
}, |
|||
{ |
|||
field: 'contactsMobile', |
|||
component: 'Input', |
|||
label: '联系人手机号', |
|||
colProps: { |
|||
span: 12, |
|||
}, |
|||
rules: [ |
|||
{ |
|||
required: true, |
|||
message: '请输入正确格式的电话号码', |
|||
pattern: |
|||
/^(1(3[0-9]|4[01456879]|5[0-3,5-9]|6[2567]|7[0-8]|8[0-9]|9[0-3,5-9])\d{8})$|^0\d{2,3}-?\d{7,8}$/, |
|||
}, |
|||
], |
|||
}, |
|||
// {
|
|||
// field: 'state',
|
|||
// component: 'Select',
|
|||
// defaultValue: 0,
|
|||
// label: '状态',
|
|||
// colProps: {
|
|||
// span: 12,
|
|||
// },
|
|||
// componentProps: {
|
|||
// options: stateTypeList,
|
|||
// disabled: true,
|
|||
// },
|
|||
// rules: [{ required: true, type: 'number' }],
|
|||
// },
|
|||
{ |
|||
field: 'description', |
|||
component: 'InputTextArea', |
|||
componentProps: { |
|||
rows: 4, |
|||
placeholder: '请输入问题描述', |
|||
showCount: true, |
|||
maxlength: 150, |
|||
}, |
|||
label: '问题描述', |
|||
colProps: { |
|||
span: 24, |
|||
}, |
|||
rules: [{ required: true }], |
|||
}, |
|||
|
|||
{ |
|||
label: '描述附件', |
|||
field: 'files', |
|||
component: 'Upload', |
|||
componentProps: { |
|||
disabled: isDetail, |
|||
customRequest: async (data) => { |
|||
console.log('data: ', data); |
|||
const formData = new FormData(); |
|||
formData.append('file', data.file); |
|||
const res = await commonUpload(formData); |
|||
console.log('res: ', res); |
|||
data?.onSuccess && data?.onSuccess(res, data.file as any); |
|||
}, |
|||
beforeUpload: (file) => { |
|||
console.log('file: ', file); |
|||
|
|||
// 限制允许上传的文件类型
|
|||
const allowedTypes = ['xlsx', 'xls', 'doc', 'docx', 'pdf', 'jpg', 'jpeg', 'png']; |
|||
|
|||
// 检查文件类型
|
|||
const fileType = getFileExtension(file.name) || 'unknown'; |
|||
if (!allowedTypes.includes(fileType)) { |
|||
// 文件类型不在允许列表中,拒绝上传
|
|||
// 可以在这里展示错误信息
|
|||
message.warning('文件类型不正确'); |
|||
return false; |
|||
} |
|||
|
|||
// 其他验证逻辑...
|
|||
|
|||
// 允许上传
|
|||
return true; |
|||
}, |
|||
}, |
|||
componentSlots: { |
|||
default: () => ( |
|||
<Button> |
|||
<UploadOutlined /> 点击上传 |
|||
</Button> |
|||
), |
|||
}, |
|||
colProps: { |
|||
span: 24, |
|||
}, |
|||
rules: [{ required: false }], |
|||
}, |
|||
{ |
|||
label: '解决方案', |
|||
field: 'solution', |
|||
colProps: { |
|||
span: 24, |
|||
}, |
|||
vShow: isDetail, |
|||
// rules: [{ required: true, type: 'array' }],
|
|||
slot: 'solution', |
|||
}, |
|||
] as any; |
|||
}; |
|||
|
|||
export const getFlowFormSchema: (row?: Partial<TableListItem>) => FormSchema[] = (record = {}) => { |
|||
return [ |
|||
{ |
|||
field: 'remark', |
|||
component: 'InputTextArea', |
|||
label: '文字补充内容', |
|||
colProps: { |
|||
span: 24, |
|||
}, |
|||
}, |
|||
]; |
|||
}; |
|||
Loading…
Reference in new issue