You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

417 lines
11 KiB
Vue

1 year ago
<template>
1 year ago
<div>
<my-card title="搜索条件" search>
<n-form inline>
12 months ago
<n-form-item style="width: 180px" label="产品分类">
<n-tree-select v-model:value="searchForm.productTypeId" :options="typeOptions" placeholder="请输入产品分类" />
1 year ago
</n-form-item>
12 months ago
<n-form-item label="产品名称">
<n-input v-model:value="searchForm.productName" placeholder="请输入产品名称" />
1 year ago
</n-form-item>
12 months ago
<n-form-item label="产品规格">
<n-input v-model:value="searchForm.specification" placeholder="请输入产品规格" />
1 year ago
</n-form-item>
<n-form-item>
12 months ago
<n-button type="primary" class="mr-10px" @click="handleSearch">
<icon-ic-round-search class="mr-4px text-20px" />
搜索
</n-button>
<n-button @click="handleReset">
<icon-ic-round-refresh class="mr-4px text-20px" />
重置
</n-button>
1 year ago
</n-form-item>
</n-form>
</my-card>
12 months ago
<my-card title="产品列表">
1 year ago
<template #right>
12 months ago
<div class="flex-center">
<n-button class="mr-5px" type="primary" size="small" @click="openDialog">
<icon-ic-round-plus class="mr-4px text-20px" />
新增产品
</n-button>
<cx-columns v-model:columns="columns" size="small"></cx-columns>
1 year ago
</div>
</template>
<n-data-table
12 months ago
ellipsis
1 year ago
:loading="loading"
:columns="columns"
:data="data"
12 months ago
:max-height="dataTableConfig.maxHeight"
:scroll-x="dataTableConfig.scrollWidth(columns)"
1 year ago
></n-data-table>
12 months ago
1 year ago
<my-pagination v-model:search-form="searchForm" @init="init"></my-pagination>
</my-card>
<my-dialog
12 months ago
:title="addForm.id ? '编辑产品' : '新增产品'"
width="750px"
:show="showDialog"
1 year ago
@cancel="cancel"
12 months ago
@submit="submit"
1 year ago
>
<template #content>
<div>
12 months ago
<n-form ref="addFormRef" :rules="rules" :model="addForm" label-placement="left" label-width="auto">
<n-grid :cols="24" :x-gap="20">
<n-form-item-grid-item label="产品分类" :span="11" path="productTypeName">
1 year ago
<n-tree-select
12 months ago
v-model:value="addForm.productTypeId"
:options="typeOptions"
placeholder="请输入产品分类"
@update:value="
(value, item: any) => {
console.log(value, item);
addForm.productTypeName = item.label;
}
"
/>
1 year ago
</n-form-item-grid-item>
12 months ago
<n-form-item-grid-item label="产品名称" :span="11" path="productTypeId">
<n-input v-model:value="addForm.productName" placeholder="请输入产品名称" />
1 year ago
</n-form-item-grid-item>
12 months ago
<n-form-item-grid-item label="产品型号" :span="11" path="productSize">
1 year ago
<n-select
12 months ago
v-model:value="addForm.productSize"
filterable
placeholder="请选择主型号"
:options="dictionaryOptions"
@update:value="dictionaryHandleChange"
/>
1 year ago
</n-form-item-grid-item>
12 months ago
<n-form-item-grid-item label="产品规格" :span="11" path="specification">
<n-input v-model:value="addForm.specification" placeholder="请输入产品规格" />
1 year ago
</n-form-item-grid-item>
12 months ago
<n-form-item-grid-item label="颜色" :span="11" path="color">
<n-select v-model:value="addForm.color" class="w-200px" :options="corlor_types" placeholder="请选择颜色" ></n-select>
</n-form-item-grid-item>
<n-form-item-grid-item label="单位" :span="11" path="weightMeasureName">
<n-select
v-model:value="addForm.weightMeasureId"
:options="unitOptions"
placeholder="请输入单位"
@update:value="
(val, item:any) => {
addForm.weightMeasureName = item.label;
}
"
/>
</n-form-item-grid-item>
<n-form-item-grid-item label="备注" :span="11">
<n-input v-model:value="addForm.remark" type="textarea" placeholder="请输入输入备注" />
1 year ago
</n-form-item-grid-item>
</n-grid>
</n-form>
</div>
</template>
</my-dialog>
</div>
1 year ago
</template>
<script setup lang="tsx">
12 months ago
defineOptions({
name: 'ListMange'
});
import type {Ref} from 'vue';
import {ref, onMounted, getCurrentInstance} from 'vue';
import {useMessage} from 'naive-ui';
import type {DataTableColumns, FormInst} from 'naive-ui';
import {useLoading, useWarning, useBoolean} from '@/hooks';
import {listToTree, deepClone, createRequiredFormRule} from '@/utils';
import {getAllClassifyList} from '@/service/api/md/classify';
import {getAllUnitList} from '@/service/api/md/unit';
import {getProductList, deleteProduct, addProduct, editProduct} from '@/service/api/md/list';
import {dataTableConfig} from '@/config/dataTableConfig';
const {loading, startLoading, endLoading} = useLoading();
const warning = useWarning();
1 year ago
const message = useMessage();
12 months ago
const {bool: showDialog, setFalse: closeDialog, setTrue: openDialog} = useBoolean();
const addFormRef = ref<FormInst | null>(null);
const routeOptions = ref<{ label: string; value: number }[]>([]);
1 year ago
12 months ago
const {proxy} = getCurrentInstance() as any;
const {product_model_standard, corlor_types} = proxy.useDict('product_model_standard', "corlor_types");
1 year ago
12 months ago
const dictionaryOptions = product_model_standard;
1 year ago
12 months ago
const addForm = ref<List.AddForm>({
processRouteName: '',
productTypeId: '',
productSize: '',
productSizeInternational: '',
processRouteId: '',
specification: '',
productName: '',
color: '',
weightMeasureId: null,
remark: '',
ifEnable: 1
1 year ago
});
12 months ago
const rules = {
productTypeId: createRequiredFormRule('请选择产品类型'),
productSize: createRequiredFormRule('请输入规格型号'),
specification: createRequiredFormRule('请输入规格型号'),
productName: createRequiredFormRule('请输入产品名称'),
weightMeasureId: createRequiredFormRule('请输入重量单位')
};
1 year ago
function cancel() {
12 months ago
closeDialog();
addForm.value = {
processRouteName: '',
productTypeId: '',
productName: '',
productSize: '',
productSizeInternational: '',
specification: '',
processRouteId: '',
color: '',
weightMeasureId: null,
remark: '',
ifEnable: 1
1 year ago
};
1 year ago
}
12 months ago
async function submit() {
console.log(addForm.value);
if (!addFormRef.value) return;
addFormRef.value.validate(async errors => {
if (!errors) {
routeOptions.value.forEach(item => {
if (item.value === parseInt(addForm.value.processRouteId as string, 10)) {
addForm.value.processRouteName = item.label;
}
});
if (!addForm.value.id) {
await addProduct(addForm.value).then(res => {
1 year ago
if (res.code === 200) {
12 months ago
message.success('新增成功');
1 year ago
cancel();
12 months ago
init();
1 year ago
}
});
} else {
12 months ago
await editProduct(addForm.value).then(res => {
1 year ago
if (res.code === 200) {
12 months ago
message.success('修改成功');
1 year ago
cancel();
12 months ago
init();
1 year ago
}
});
}
}
});
1 year ago
}
12 months ago
const searchForm = ref<List.SearchForm>({
productTypeId: '',
productName: '',
specification: '',
pageNum: 1,
pageSize: 10,
total: 0
});
function dictionaryHandleChange(val, item) {
addForm.value.productSize = item.label;
addForm.value.productSizeInternational = val;
}
function handleSearch() {
console.log(searchForm.value);
init();
}
function handleReset() {
searchForm.value = {
productTypeId: '',
productName: '',
specification: '',
pageNum: 1,
pageSize: 10,
total: 0
};
init();
}
const columns: Ref<DataTableColumns<List.DataForm>> = ref([
{
title: '序号',
key: 'index',
align: 'center',
width: 60,
render: (_row, index) => (searchForm.value.pageNum - 1) * searchForm.value.pageSize + index + 1
},
1 year ago
{
12 months ago
title: '产品分类',
key: 'productTypeName',
align: 'center',
width: 80
1 year ago
},
{
12 months ago
title: '产品名称',
key: 'productName',
align: 'center',
1 year ago
width: 100
},
{
12 months ago
title: '产品编码',
key: 'productCode',
align: 'center',
width: 130,
ellipsis: {
tooltip: true
}
1 year ago
},
{
12 months ago
title: '产品型号',
key: 'productSize',
align: 'center',
width: 120
1 year ago
},
{
12 months ago
title: '颜色',
align: 'center',
key: 'color'
1 year ago
},
{
12 months ago
title: '颜色名称',
key: 'status',
align: 'center',
render: row => {
return <dict-tag options={corlor_types.value} value={row.color}></dict-tag>;
},
width: 110,
ellipsis: {
tooltip: true
}
1 year ago
},
{
12 months ago
title: '国际型号',
key: 'productSizeInternational',
align: 'center',
width: 120
1 year ago
},
{
12 months ago
title: '产品规格',
key: 'specification',
align: 'center',
width: 80
1 year ago
},
{
12 months ago
title: '单位',
key: 'weightMeasureName',
1 year ago
align: 'center',
12 months ago
width: 80
1 year ago
},
// {
12 months ago
// title: '创建时间',
// key: 'createTime',
// width: 200
1 year ago
// },
12 months ago
{
title: '备注',
align: 'center',
key: 'remark',
width: 200
},
1 year ago
{
title: '操作',
key: 'action',
12 months ago
align: 'center',
1 year ago
fixed: 'right',
12 months ago
width: 160,
render(row) {
return (
<div>
<n-button size="small" type="info" class="mr-5px" onClick={() => handleEdit(row)}>
<icon-tdesign-edit class="mr-1px text-15px "/>
编辑
</n-button>
<n-button
size="small"
type="error"
class="mr-5px"
onClick={() => {
warning.warn(() => {
deleteProduct({id: row.id}).then(res => {
if (res.code === 200) {
message.success('删除成功');
init();
} else {
message.error('删除失败');
}
1 year ago
});
});
12 months ago
}}
>
<icon-tdesign-delete class="mr-1px text-15px "/>
删除
</n-button>
</div>
1 year ago
);
}
}
1 year ago
]);
12 months ago
// function optionsToObject(options: { label: string; value: string }[]) {
// const obj = {};
// options.forEach(item => {
// obj[item.value] = item.label;
// });
// return obj;
// }
const data = ref<List.DataForm[]>([]);
function handleEdit(row: List.DataForm) {
addForm.value = deepClone(row);
openDialog();
console.log(row);
}
const typeOptions = ref<{ label: string; value: string }[]>([]);
const unitOptions = ref<{ label: string; value: string }[]>([]);
async function init() {
// typeOptions.value.splice(0, typeOptions.value.length);
1 year ago
startLoading();
12 months ago
await getProductList(searchForm.value).then(res => {
console.log(res);
1 year ago
data.value = res.rows;
searchForm.value.total = res.total;
});
12 months ago
1 year ago
endLoading();
1 year ago
}
onMounted(() => {
12 months ago
init();
// 获取单位Options
getAllUnitList().then(res => {
1 year ago
console.log(res);
12 months ago
res.data.forEach(item => {
unitOptions.value.push({
label: item.measureName,
value: item.id
1 year ago
});
});
});
12 months ago
// 获取类型Options
getAllClassifyList({pageNum: 1}).then(res => {
const list: any[] = [];
1 year ago
res.data.forEach(item => {
12 months ago
list.push({
id: item.id,
parentTypeId: item.parentTypeId,
key: item.id,
label: item.typeName
1 year ago
});
});
12 months ago
typeOptions.value = listToTree(list, 'id', 'parentTypeId');
1 year ago
});
1 year ago
});
</script>
12 months ago
<style lang="scss" scoped></style>