feat(material-center): 增加原料库编辑功能并优化列表展示

- 新增原料库编辑功能,包括修改名称、标签等信息
This commit is contained in:
rd
2025-09-17 17:08:58 +08:00
parent 05fd0f912f
commit 11f49e048d
6 changed files with 230 additions and 5 deletions

View File

@ -200,10 +200,10 @@ export const postBatchRawMaterial = (params = {}) => {
// 原料库-修改 // 原料库-修改
export const putRawMaterial = (params = {}) => { export const putRawMaterial = (params = {}) => {
const { id, ...rest } = params as { id: string; [key: string]: any }; const { id, ...rest } = params as { id: string; [key: string]: any };
return Http.put(`/v1/raw-material/${id}`, rest); return Http.put(`/v1/raw-materials/${id}`, rest);
}; };
// 原料库-详情 // 原料库-详情
export const getRawMaterialDetail = (id: string) => { export const getRawMaterialDetail = (id: string) => {
return Http.get(`/v1/raw-material/${id}`); return Http.get(`/v1/raw-materials/${id}`);
}; };

View File

@ -0,0 +1,211 @@
<script lang="tsx">
import { ref } from 'vue';
import { Button, Modal, Form, FormItem, Input, message, Select } from 'ant-design-vue';
const { TextArea } = Input;
import { formatFileSize, exactFormatTime } from '@/utils/tools';
import { getRawMaterialDetail, putRawMaterial, getRawMaterialTagsList } from '@/api/all/generationWorkshop';
import { TABS_LIST, ORIGIN_LIST } from '@/views/material-center/components/raw-material/constants';
const INITIAL_FORM = {
name: '',
tag_ids: [],
uid: '',
type: '',
origin: '',
size: '',
created_at: '',
uploader: {
name: '',
mobile: '',
},
};
export default {
setup(props, { emit, expose }) {
const formRef = ref();
const id = ref('');
const visible = ref(false);
const submitLoading = ref(false);
const form = ref(cloneDeep(INITIAL_FORM));
const tagOptions = ref([]);
const rules = {
mobile: [
{
required: true,
validator: (_rule, value) => {
if (!value) {
return Promise.reject('请填写手机号');
}
if (!/^1[3-9]\d{9}$/.test(value)) {
return Promise.reject('手机号格式不正确');
} else {
return Promise.resolve();
}
},
trigger: ['blur', 'change'],
},
],
operator_name: [{ required: true, message: '请输入运营人员' }],
};
const getMaterialDetail = async () => {
const { code, data } = await getRawMaterialDetail(id.value);
if (code === 200) {
form.value = data;
}
};
const getTags = async () => {
const { code, data } = await getRawMaterialTagsList();
if (code === 200) {
tagOptions.value = data;
}
};
const reset = () => {
form.value = cloneDeep(INITIAL_FORM);
tagOptions.value = [];
submitLoading.value = false;
id.value = '';
};
const open = (materialId = '') => {
id.value = materialId;
getMaterialDetail();
getTags();
visible.value = true;
};
const onClose = () => {
reset();
visible.value = false;
};
const onSubmit = () => {
formRef.value.validate().then(async () => {
try {
submitLoading.value = true;
const { code } = await putRawMaterial({ id: id.value, ...form.value });
if (code === 200) {
message.success('修改成功');
emit('update');
onClose();
}
} finally {
submitLoading.value = false;
}
});
};
expose({ open });
return () => (
<Modal
v-model:open={visible.value}
title="编辑素材"
wrapClassName="edit-material-modal"
width="480px"
centered
maskClosable={false}
onCancel={onClose}
v-slots={{
footer: () => (
<div class="flex">
<Button onClick={onClose}>取消</Button>
<Button type="primary" loading={submitLoading.value} onClick={onSubmit}>
确定
</Button>
</div>
),
}}
>
<Form
ref={formRef}
model={form.value}
rules={rules}
layout="horizontal"
labelAlign="right"
labelCol={{ span: 4 }}
wrapperCol={{ span: 20 }}
>
<FormItem label="文件名称" name="name">
<TextArea
v-model:value={form.value.name}
placeholder="请输入..."
size="large"
class="!h-72px"
showCount
maxlength={20}
/>
</FormItem>
<FormItem label="序号" name="uid">
<Input v-model:value={form.value.uid} placeholder="请输入..." size="large" disabled />
</FormItem>
<FormItem label="类型" name="type">
<Input
value={TABS_LIST.find((item) => item.value === form.value.type)?.label ?? '-'}
placeholder="请输入..."
size="large"
disabled
/>
</FormItem>
<FormItem label="标签" name="tag_ids" v-model:value={form.value.tag_ids}>
<Select
v-model:value={form.value.tag_ids}
mode="tags"
size="middle"
placeholder="请选择标签"
allowClear
class="w-full"
showSearch
showArrow
maxTagCount={5}
maxTagTextLength={5}
onInputKeyDown={(e) => {
// 检测回车键
if (e.key === 'Enter') {
e.preventDefault();
// handleTagInputPressEnter(e);
}
}}
>
{tagOptions.value.map((item) => (
<Select.Option value={item.id} key={item.id}>
{item.name}
</Select.Option>
))}
</Select>
</FormItem>
<FormItem label="来源" name="origin">
<Input
value={ORIGIN_LIST.find((item) => item.value === form.value.origin)?.label ?? '-'}
placeholder="请输入..."
size="large"
disabled
/>
</FormItem>{' '}
<FormItem label="大小" name="size">
<Input value={formatFileSize(form.value.size)} placeholder="请输入..." size="large" disabled />
</FormItem>
<FormItem label="上传时间" name="created_at">
<Input value={exactFormatTime(form.value.created_at)} placeholder="请输入..." size="large" disabled />
</FormItem>
<FormItem label="上传人员" name="uploader">
<Input
value={form.value.uploader.name || form.value.uploader.mobile}
placeholder="请输入..."
size="large"
disabled
/>
</FormItem>
</Form>
</Modal>
);
},
};
</script>
<style lang="scss">
@import './style.scss';
</style>

View File

@ -76,7 +76,10 @@
<template v-else-if="column.dataIndex === 'operation'" #customRender="{ record }"> <template v-else-if="column.dataIndex === 'operation'" #customRender="{ record }">
<div class="flex items-center"> <div class="flex items-center">
<img class="mr-8px cursor-pointer" :src="icon1" width="14" height="14" @click="onDelete(record)" /> <img class="mr-8px cursor-pointer" :src="icon1" width="14" height="14" @click="onDelete(record)" />
<Button type="primary" ghost size="small" @click="onDownload(record)">下载</Button> <Button class="mr-8px !h-24px !px-12px" ghost size="small" type="primary" @click="onEdit(record)"
>编辑
</Button>
<Button class="!h-24px !px-12px" ghost size="small" type="primary" @click="onDownload(record)">下载</Button>
</div> </div>
</template> </template>
<template v-else #customRender="{ record }"> <template v-else #customRender="{ record }">
@ -102,7 +105,7 @@ import ImgLazyLoad from '@/components/img-lazy-load';
import icon1 from '@/assets/img/media-account/icon-delete.png'; import icon1 from '@/assets/img/media-account/icon-delete.png';
import icon2 from '../../img/icon-no-text.png'; import icon2 from '../../img/icon-no-text.png';
const emits = defineEmits(['sorterChange', 'delete', 'select', 'selectAll']); const emits = defineEmits(['sorterChange', 'delete', 'select', 'selectAll', 'edit']);
const router = useRouter(); const router = useRouter();
const props = defineProps({ const props = defineProps({
@ -143,6 +146,9 @@ const onDelete = (item) => {
const onDownload = (item) => { const onDownload = (item) => {
downloadByUrl(item.file); downloadByUrl(item.file);
}; };
const onEdit = (item) => {
emits('edit', item);
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@ -90,7 +90,7 @@ export const TABLE_COLUMNS = [
{ {
title: '操作', title: '操作',
dataIndex: 'operation', dataIndex: 'operation',
width: 120, width: 180,
fixed: 'right', fixed: 'right',
}, },
]; ];

View File

@ -8,6 +8,7 @@ import RawMaterialTable from './components/table/index.vue';
import DeleteRawMaterialModal from './components/table/delete-file-modal.vue'; import DeleteRawMaterialModal from './components/table/delete-file-modal.vue';
import TagsManageModal from './components/tags-manage-modal'; import TagsManageModal from './components/tags-manage-modal';
import AddRawMaterialDrawer from './components/add-raw-material-drawer'; import AddRawMaterialDrawer from './components/add-raw-material-drawer';
import EditRawMaterialDrawer from './components/edit-raw-material-modal';
import { useTableSelectionWithPagination } from '@/hooks/useTableSelectionWithPagination'; import { useTableSelectionWithPagination } from '@/hooks/useTableSelectionWithPagination';
import { getRawMaterialsPage } from '@/api/all/generationWorkshop'; import { getRawMaterialsPage } from '@/api/all/generationWorkshop';
@ -34,6 +35,7 @@ export default defineComponent({
const deleteRawMaterialModalRef = ref(null); const deleteRawMaterialModalRef = ref(null);
const tagsManageModalRef = ref(null); const tagsManageModalRef = ref(null);
const addRawMaterialDrawerRef = ref(null); const addRawMaterialDrawerRef = ref(null);
const editRawMaterialDrawerRef = ref(null);
const query = ref(cloneDeep(INITIAL_QUERY)); const query = ref(cloneDeep(INITIAL_QUERY));
const handleSearch = () => { const handleSearch = () => {
@ -78,6 +80,10 @@ export default defineComponent({
deleteRawMaterialModalRef.value?.open({ id, name: `${name}` }); deleteRawMaterialModalRef.value?.open({ id, name: `${name}` });
}; };
const handleEdit = (item) => {
editRawMaterialDrawerRef.value?.open(item.id);
};
const handleTabClick = (key) => { const handleTabClick = (key) => {
query.value.type = key; query.value.type = key;
reload(); reload();
@ -166,6 +172,7 @@ export default defineComponent({
onDelete={handleDelete} onDelete={handleDelete}
onSelect={handleSelect} onSelect={handleSelect}
onSelectAll={handleSelectAll} onSelectAll={handleSelectAll}
onEdit={handleEdit}
/> />
{pageInfo.value.total > 0 && ( {pageInfo.value.total > 0 && (
<div class="pagination-row"> <div class="pagination-row">
@ -185,6 +192,7 @@ export default defineComponent({
<TagsManageModal ref={tagsManageModalRef} /> <TagsManageModal ref={tagsManageModalRef} />
<AddRawMaterialDrawer ref={addRawMaterialDrawerRef} onUpdate={getData} /> <AddRawMaterialDrawer ref={addRawMaterialDrawerRef} onUpdate={getData} />
<EditRawMaterialDrawer ref={editRawMaterialDrawerRef} onUpdate={getData} />
<DeleteRawMaterialModal ref={deleteRawMaterialModalRef} onBatchUpdate={onBatchSuccess} onUpdate={getData} /> <DeleteRawMaterialModal ref={deleteRawMaterialModalRef} onBatchUpdate={onBatchSuccess} onUpdate={getData} />
</div> </div>
); );