优化代码

main
GaoF 2024-09-15 23:05:46 +08:00
parent 57357e320a
commit cf10261ecf
43 changed files with 3076 additions and 547 deletions

View File

@ -8,6 +8,7 @@
borderRadius: roundedCornerStyleOpen ? 6 : 2 borderRadius: roundedCornerStyleOpen ? 6 : 2
} }
}" }"
:getPopupContainer="getPopupContainer"
> >
<a-watermark <a-watermark
:content="loginUserWatermarkOpen && userInfo ? [userInfo.name, userInfo.account] : undefined" :content="loginUserWatermarkOpen && userInfo ? [userInfo.name, userInfo.account] : undefined"
@ -37,4 +38,21 @@
const roundedCornerStyleOpen = computed(() => { const roundedCornerStyleOpen = computed(() => {
return store.roundedCornerStyleOpen return store.roundedCornerStyleOpen
}) })
const getPopupContainer = (el, dialogContext) => {
if (dialogContext) {
return dialogContext.getDialogWrap()
} else {
return document.body
}
}
</script> </script>
<style>
.ant-table-wrapper .ant-table-thead > tr > th {
/* 样式规则 */
background-color: #f2f6fc; /* 表头背景色 */
color: #606266; /* 表头字体颜色 */
font-weight: bold;
}
</style>

View File

@ -0,0 +1,34 @@
import { baseRequest } from '@/utils/request'
const request = (url, ...arg) => baseRequest(`/productcode/producerecords/` + url, ...arg)
/**
* 产品条码历史记录Api接口管理器
*
* @author Luck
* @date 2024/09/15 13:56
**/
export default {
// 获取产品条码历史记录分页
produceBarcodeHistoryPage(data) {
return request('page', data, 'get')
},
// 提交产品条码历史记录表单 edit为true时为编辑默认为新增
produceBarcodeHistorySubmitForm(data, edit = false) {
return request(edit ? 'edit' : 'add', data)
},
// 删除产品条码历史记录
produceBarcodeHistoryDelete(data) {
return request('delete', data)
},
// 获取产品条码历史记录详情
produceBarcodeHistoryDetail(data) {
return request('detail', data, 'get')
},
// 获取产品条码历史记录详情
produceBarcodeHistoryAgainExport(data) {
return request('againExport', data, 'get', {
responseType: 'blob'
})
}
}

View File

@ -0,0 +1,32 @@
import { baseRequest } from '@/utils/request'
const request = (url, ...arg) => baseRequest(`/productcode/config/` + url, ...arg)
/**
* 产码配置Api接口管理器
*
* @author luojun
* @date 2024/08/31 17:15
**/
export default {
// 获取产码配置分页
productCodeConfigPage(data) {
return request('page', data, 'get')
},
// 获取产码配置列表
productCodeConfigList(data) {
return request('list', data, 'get')
},
// 提交产码配置表单 edit为true时为编辑默认为新增
productCodeConfigSubmitForm(data, edit = false) {
return request(edit ? 'edit' : 'add', data)
},
// 删除产码配置
productCodeConfigDelete(data) {
return request('delete', data)
},
// 获取产码配置详情
productCodeConfigDetail(data) {
return request('detail', data, 'get')
}
}

View File

@ -0,0 +1,36 @@
import { baseRequest } from '@/utils/request'
const request = (url, ...arg) => baseRequest(`/productcode/element/` + url, ...arg)
/**
* 产码配置元素表Api接口管理器
*
* @author luojun
* @date 2024/08/31 16:14
**/
export default {
// 获取产码配置元素表分页
productCodeConfigElementPage(data) {
return request('page', data, 'get')
},
// 获取产码配置元素表列表
productCodeConfigElementList(data) {
return request('list', data, 'get')
},
// 提交产码配置元素表表单 edit为true时为编辑默认为新增
productCodeConfigElementSubmitForm(data, edit = false) {
return request(edit ? 'edit' : 'add', data)
},
// 删除产码配置元素表
productCodeConfigElementDelete(data) {
return request('delete', data)
},
// 获取产码配置元素表详情
productCodeConfigElementDetail(data) {
return request('detail', data, 'get')
},
// 批量保存码元素
productCodeConfigElementBatchSave(data) {
return request('batchSave', data, 'post')
}
}

View File

@ -0,0 +1,32 @@
import { baseRequest } from '@/utils/request'
const request = (url, ...arg) => baseRequest(`/productcode/packageconfig/` + url, ...arg)
/**
* 产码码包配置Api接口管理器
*
* @author luojun
* @date 2024/08/31 19:31
**/
export default {
// 获取产码码包配置分页
productCodePackageConfigPage(data) {
return request('page', data, 'get')
},
// 获取产码码包配置列表
productCodePackageConfigList(data) {
return request('list', data, 'get')
},
// 提交产码码包配置表单 edit为true时为编辑默认为新增
productCodePackageConfigSubmitForm(data, edit = false) {
return request(edit ? 'edit' : 'add', data)
},
// 删除产码码包配置
productCodePackageConfigDelete(data) {
return request('delete', data)
},
// 获取产码码包配置详情
productCodePackageConfigDetail(data) {
return request('detail', data, 'get')
}
}

View File

@ -0,0 +1,35 @@
import { baseRequest } from '@/utils/request'
const request = (url, ...arg) => baseRequest(`/productcode/scheme/` + url, ...arg)
const requestCode = (url, ...arg) => baseRequest(`/productcode/controller/` + url, ...arg)
/**
* 产码方案Api接口管理器
*
* @author luojun
* @date 2024/08/31 10:25
**/
export default {
// 获取产码方案分页
productCodeSchemePage(data) {
return request('page', data, 'get')
},
// 提交产码方案表单 edit为true时为编辑默认为新增
productCodeSchemeSubmitForm(data, edit = false) {
return request(edit ? 'edit' : 'add', data)
},
// 删除产码方案
productCodeSchemeDelete(data) {
return request('delete', data)
},
// 获取产码方案详情
productCodeSchemeDetail(data) {
return request('detail', data, 'get')
},
// 产码生成
productCodeSchemeProduce(data) {
return requestCode('produce', data, 'get', {
responseType: 'blob'
})
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -0,0 +1,124 @@
<template>
<div class="ant-dropdown-menu s-tool-column ant-dropdown-content">
<div class="s-tool-column-header s-tool-column-item">
<a-checkbox :indeterminate="indeterminate" :checked="checkAll" @change="onCheckAllChange"> </a-checkbox>
<a @click="reset"></a>
</div>
<a-divider />
<div class="ant-checkbox-group">
<div>
<draggable :list="columnsSetting" item-key="dataIndex" animation="300" @end="emitColumnChange">
<template #item="{ element }">
<div class="s-tool-column-item">
<div class="s-tool-column-handle layout-items-center">
<more-outlined />
<more-outlined />
</div>
<a-checkbox v-model:checked="element.checked" @change="onChange">{{ element.title }}</a-checkbox>
</div>
</template>
</draggable>
</div>
</div>
</div>
</template>
<script setup>
import Draggable from 'vuedraggable-es'
const emit = defineEmits(['columnChange'])
const props = defineProps({
columns: {
type: Array,
default: () => []
}
})
const indeterminate = ref(false)
const checkAll = ref(true)
const columnsSetting = ref([])
const originColumns = ref()
onMounted(() => {
columnsSetting.value = props.columns.map((value) => {
if (value.checked === undefined) {
return {
...value,
checked: true
}
} else return value
})
// originColumns
originColumns.value = columnsSetting.value.map((value) => ({ ...value }))
//
const notCheckedList = columnsSetting.value.filter((value) => !value.checked)
if (notCheckedList.length) checkAll.value = false
})
const reset = () => {
columnsSetting.value = originColumns.value.map((value) => ({ ...value }))
indeterminate.value = false
const checkedList = columnsSetting.value.filter((value) => value.checked)
checkAll.value = checkedList.length === columnsSetting.value.length
emitColumnChange()
}
const onChange = () => {
const checkedList = columnsSetting.value.filter((value) => value.checked)
indeterminate.value = Boolean(checkedList.length) && checkedList.length < columnsSetting.value.length
checkAll.value = checkedList.length === columnsSetting.value.length
emitColumnChange()
}
//
const onCheckAllChange = (e) => {
e.preventDefault()
const val = e.target.checked
indeterminate.value = false
checkAll.value = val
columnsSetting.value = props.columns.map((value) => ({
...value,
checked: val
}))
emitColumnChange()
}
const emitColumnChange = () => {
// eslint-disable-next-line vue/require-explicit-emits
emit('columnChange', columnsSetting.value)
}
</script>
<style lang="less" scoped>
.s-tool-column-item {
display: flex;
align-items: center;
padding: 4px 16px 4px 4px;
.ant-checkbox-wrapper {
flex: 1;
}
.s-tool-column-handle {
opacity: 0.8;
cursor: move;
.anticon-more {
font-size: 12px;
& + .anticon-more {
margin: 0px 4px 0 -8px;
}
}
}
}
.s-tool-column-header {
padding: 5px 16px 10px 24px;
min-width: 180px;
}
.s-tool-column {
.ant-divider {
margin: 0;
}
.ant-checkbox-group {
padding: 4px 0;
display: block;
}
}
</style>

View File

@ -1,145 +1,731 @@
<template> <template>
<div class="table-wrapper"> <div className="table-wrapper">
<!-- 工具栏 --> <div className="s-table-tool">
<div class="table-tool"> <div className="s-table-tool-left">
<a-button @click="addRow" type="primary">新增</a-button> <!-- 插槽操作按钮 -->
<a-button @click="addRow" type="primary">删除</a-button> <slot name="operator"></slot>
</div> </div>
<!-- 斑马纹 -->
<div className="layout-items-center s-table-tool-right">
<div className="layout-items-center ml-4" v-show="props.toolConfig.striped">
<a-checkbox :checked="data.localSettings.rowClassNameSwitch" @change="changeRowClass"> </a-checkbox>
</div>
<span v-for="item in tool" :key="item.name">
<!-- 新增 -->
<a-tooltip
v-if="item.name === 'plus' && props.toolConfig.plus"
:title="item.title"
class="s-tool-item"
@click="
() => {
emit('plusRowData')
}
"
>
<component class="icons" :is="item.icon"></component>
</a-tooltip>
<!-- 修改 -->
<a-tooltip
v-if="item.name === 'edit' && props.toolConfig.edit"
:title="item.title"
class="s-tool-item"
@click="
() => {
emit('editRowData')
}
"
>
<component class="icons" :is="item.icon"></component>
</a-tooltip>
<!-- 删除 -->
<a-tooltip v-if="item.name === 'delete' && props.toolConfig.delete" :title="item.title" class="s-tool-item">
<a-popconfirm
v-if="item.name === 'delete' && props.toolConfig.delete"
title="确定要删除吗?"
ok-text="确认"
cancel-text="取消"
@confirm="
() => {
emit('deleteRowData')
}
"
>
<component class="icons" :is="item.icon"></component>
</a-popconfirm>
</a-tooltip>
<!-- 刷新 -->
<a-tooltip
v-if="item.name === 'refresh' && props.toolConfig.refresh"
:title="item.title"
class="s-tool-item"
@click="refresh"
>
<component class="icons" :is="item.icon"></component>
</a-tooltip>
<!-- 列展示 -->
<a-popover
v-if="item.isPopover && item.name === 'columnSetting' && props.toolConfig.columnSetting"
trigger="click"
placement="topLeft"
overlayClassName="s-table-column-settings"
arrow-point-at-center
>
<template #content>
<columnSetting :columns="props.columns" @columnChange="columnChange" />
</template>
<a-tooltip :title="item.title" class="s-tool-item">
<component class="icons" :is="item.icon"></component>
</a-tooltip>
</a-popover>
<!-- 密度 -->
<a-dropdown trigger="click" v-if="item.isDropdown && item.name === 'height' && props.toolConfig.height">
<template #overlay>
<a-menu selectable :selectedKeys="[data.customSize]" @click="changeHeight">
<a-menu-item key="default">默认</a-menu-item>
<a-menu-item key="middle">中等</a-menu-item>
<a-menu-item key="small">紧凑</a-menu-item>
</a-menu>
</template>
<a-tooltip :title="item.title" class="s-tool-item">
<component class="icons" :is="item.icon"></component>
</a-tooltip>
</a-dropdown>
</span>
</div>
</div>
<!-- 统计列数据 -->
<a-alert showIcon class="mb-4" v-if="props.alert">
<template #message>
<div>
<span className="mr-3">
已选择:{{ ' ' }}
<a className="font-6">
{{
props.rowSelection && props.rowSelection.selectedRowKeys ? props.rowSelection.selectedRowKeys.length : 0
}}
</a>
</span>
<span className="mr-3" v-for="item in data.needTotalList">
{{ item.title }} 总计{{ ' ' }}
<a className="font-6">{{ !item.customRender ? item.total : item.customRender(item.total) }}</a>
</span>
<a
v-show="
props.rowSelection && props.rowSelection.selectedRowKeys && props.rowSelection.selectedRowKeys.length > 0
"
className="ml-6"
@click="
rowClear(
typeof props.alert === 'boolean' && props.alert
? clearSelected()
: props.alert.clear && typeof props.alert.clear === 'function'
? props.alert.clear()
: null
)
"
>
{{ ' ' }}
清空{{ ' ' }}
</a>
</div>
</template>
</a-alert>
<!-- 表格 --> <!-- 表格 -->
<a-table <a-table
size="middle" v-bind="{ ...renderTableProps }"
:dataSource="dataSource" :loading="data.localLoading"
:columns="computedColumns" :data-source="dataSource"
:rowKey="rowKey" @expand="
@change="handleTableChange" (expanded, record) => {
:scroll="{ x: 'max-content' }" emit('expand', expanded, record)
:row-selection="rowSelection" }
"
@resizeColumn="handleResizeColumn"
:rowClassName="
(record, index) => (data.localSettings.rowClassNameSwitch ? ((index + 1) % 2 == 0 ? 'odd' : '') : null)
"
:scroll="scroll"
> >
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record, index }">
<template v-if="column.editable"> <template v-if="column?.dataIndex === 'index'">
{{ index + 1 }}
</template>
<template v-if="isEditable(column)">
<component <component
style="width: 100%" :is="getEditorComponent(column)"
:is="getComponent(column.dataType)"
v-model:value="record[column.dataIndex]"
:options="column.options"
v-bind="column.attrs" v-bind="column.attrs"
v-model:value="record[column.dataIndex]"
@change="onCellChange(record, column)"
:placeholder="'请输入' + column.title"
style="width: 100%"
/> />
</template> </template>
<template v-else> <template v-if="!isEditable(column)">
<span>{{ record[column.dataIndex] }}</span> {{ record[column?.dataIndex] }}
</template> </template>
<template v-if="column?.slot">
<slot name="action" v-bind="{ record, index }" />
</template> </template>
<template #actions="{ record }">
<a-button @click="edit(record[props.rowKey])" size="small">编辑</a-button>
<a-popconfirm title="确定删除吗?" @confirm="() => deleteRow(record[props.rowKey])">
<a-button type="danger" size="small">删除</a-button>
</a-popconfirm>
</template> </template>
</a-table> </a-table>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, reactive, computed, defineProps } from 'vue' import { tableProps } from 'ant-design-vue/es/table/Table.js'
import columnSetting from './columnSetting.vue'
import { useSlots } from 'vue'
import { useRoute } from 'vue-router'
import { get } from 'lodash-es'
const slots = useSlots()
const route = useRoute()
const emit = defineEmits(['expand', 'plusRowData', 'editRowData', 'deleteRowData', 'refresh'])
const renderSlots = Object.keys(slots)
// defineProps const props = defineProps(
const props = defineProps({ Object.assign({}, tableProps(), {
initialData: {
type: Array,
default: () => []
},
columns: {
type: Array,
default: () => []
},
rowKey: { rowKey: {
type: String, type: [String, Function],
default: 'key' default: 'key'
},
data: {
type: [Function, Array],
required: false
},
dataSource: {
type: [Array],
required: false,
default: () => []
},
pageNum: {
type: Number,
default: 1
},
size: {
type: Number,
default: 10
},
showSizeChanger: {
type: Boolean,
default: true
},
compSize: {
type: String,
default: 'middle'
},
alert: {
type: [Object, Boolean],
default: null
},
rowSelection: {
type: Object,
default: null
},
lineSelection: {
type: Boolean,
default: false
},
customRow: {
type: Function,
default: undefined
},
showPagination: {
type: [String, Boolean],
default: 'auto'
},
defaultPageSize: {
type: Number,
default: 10
},
pageSizeOptions: {
type: Array,
default: () => ['10', '20', '50', '100']
},
extraTool: {
type: Array,
default: () => []
},
//
toolConfig: {
type: Object,
default: () => ({
plus: false,
edit: false,
delete: false,
refresh: false,
height: false,
columnSetting: false,
striped: false
})
},
scroll: {
type: Object,
default: {
x: '100%'
}
}
})
)
const data = reactive({
needTotalList: [],
localDataSource: [],
localPagination: Object.assign({}, props.pagination),
isFullscreen: false,
customSize: props.compSize,
columnsSetting: [],
localSettings: {
rowClassName: props.rowClassName,
rowClassNameSwitch: Boolean(props.rowClassName)
} }
}) })
// watch(
const dataSource = ref([...props.initialData]) () => props.pageNum,
const editingKey = ref(null) (newVal) => {
Object.assign(data.localPagination, {
current: newVal
})
}
)
watch(
() => props.size,
(newVal) => {
Object.assign(data.localPagination, {
size: newVal
})
}
)
watch(
() => props.showSizeChanger,
(newVal) => {
Object.assign(data.localPagination, {
showSizeChanger: newVal
})
}
)
watch(
() => props.columns,
(newVal) => {
data.columnsSetting = newVal
}
)
watch(
() => props.dataSource,
(newVal) => {
data.columnsSetting = newVal
}
)
// //
const getComponent = (dataType) => { const handleResizeColumn = (w, col) => {
switch (dataType) { col.width = w
case 'number': }
return 'a-input-number'
case 'select': // props
return 'a-select' const renderTableProps = ref([])
default: //
const tool = [
{
name: 'plus',
icon: 'plus-outlined',
title: '新增'
},
{
name: 'edit',
icon: 'edit-outlined',
title: '编辑'
},
{
name: 'delete',
icon: 'delete-outlined',
title: '删除'
},
{
name: 'refresh',
icon: 'sync-outlined',
title: '刷新'
},
{
name: 'height',
icon: 'column-height-outlined',
title: '密度',
isDropdown: true
},
{
name: 'columnSetting',
icon: 'setting-outlined',
title: '列设置',
isPopover: true,
visible: false
}
]
//
const refresh = (bool = false) => {
console.log(123131)
bool &&
(data.localPagination = Object.assign(
{},
{
current: 1,
pageSize: data.localPagination.pageSize
}
))
loadData()
getTableProps()
emit('refresh')
}
//
const changeRowClass = (v) => {
data.localSettings.rowClassNameSwitch = v.target.checked
getTableProps()
}
//
const changeHeight = (v) => {
data.customSize = v.key
getTableProps()
}
//
const columnChange = (v) => {
data.columnsSetting = v
getTableProps()
}
//
const rowClear = (callback) => {
clearSelected()
}
//
const init = () => {
const { current } = route.params
const localPageNum = (current && parseInt(current)) || props.pageNum
data.localPagination =
(['auto', true].includes(props.showPagination) &&
Object.assign({}, data.localPagination, {
current: localPageNum,
pageSize: props.size, //props.compSize, size//
showSizeChanger: props.showSizeChanger,
defaultPageSize: props.defaultPageSize,
pageSizeOptions: props.pageSizeOptions,
showTotal: (total, range) => {
return `${range[0]}-${range[1]}${total}`
}
})) ||
false
data.needTotalList = initTotalList(props.columns)
data.columnsSetting = props.columns
loadData()
}
const initTotalList = (columns) => {
const totalList = []
columns &&
columns instanceof Array &&
columns.forEach((column) => {
if (column.needTotal) {
totalList.push({
...column,
total: 0
})
}
})
return totalList
}
//
const loadData = (pagination, filters, sorter) => {
// loading
data.localLoading = true
//
const parameter = Object.assign(
{
current:
(pagination && pagination.current) || (props.showPagination && data.localPagination.current) || props.pageNum,
// 使size
size:
(pagination && pagination.pageSize) ||
(props.showPagination && data.localPagination.pageSize) ||
props.pageSize ||
data.localPagination.pageSize
},
(sorter &&
sorter.field && {
sortField: sorter.field
}) ||
{},
(sorter &&
sorter.order && {
sortOrder: sorter.order
}) ||
{},
{
...filters
}
)
//
if (typeof props.data !== 'function') {
data.localLoading = false
data.localDataSource = props.data
getTableProps()
} else {
const result = props.data(parameter)
if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') {
result
.then((r) => {
if (r == null) {
data.localLoading = false
return
}
//
data.localPagination =
(props.showPagination &&
Object.assign({}, data.localPagination, {
current: r.current, // pageNo, //
total: r.total, // totalRows, //
showSizeChanger: props.showSizeChanger,
pageSizeOptions: props.pageSizeOptions,
showTotal: (total, range) => {
return `${range[0]}-${range[1]}${total}`
},
pageSize: (pagination && pagination.pageSize) || data.localPagination.pageSize
})) ||
false
// recordsnull
if (r.records == null) {
r.records = []
}
// 0 ,
if (r.records.length === 0 && props.showPagination && data.localPagination.current > 1) {
data.localPagination.current--
loadData()
return
}
try {
// table
//
// if ((['auto', true].includes(props.showPagination) && r.total <= (r.pages * data.localPagination.pageSize))) {
// data.localPagination.hideOnSinglePage = true
// }
if (!props.showPagination) {
data.localPagination.hideOnSinglePage = true
}
} catch (e) {
data.localPagination = false
}
//
if (props.showPagination === false) {
data.localDataSource = r instanceof Array ? r : r.records
} else {
data.localDataSource = r.records
}
getTableProps()
})
.catch(() => {})
.finally(() => {
data.localLoading = false
})
}
}
}
// tableprops
const getTableProps = () => {
let renderProps = {}
const localKeys = Object.keys(data)
// antdAPI
Object.keys(Object.assign(tableProps(), props)).forEach((k) => {
// localdataAPI
const localKey = `local${k.substring(0, 1).toUpperCase()}${k.substring(1)}`
// table props
if (localKeys.includes(localKey)) {
renderProps[k] = data[localKey]
return
}
// alert rowSelection
// rowSelection
if (k === 'rowSelection') {
renderProps[k] = props.rowSelection
? {
...props.rowSelection,
onChange: (selectedRowKeys, selectedRows) => {
updateSelect(selectedRowKeys, selectedRows)
typeof props[k].onChange !== 'undefined' && props[k].onChange(selectedRowKeys, selectedRows)
}
}
: null
return
}
// ,
if (k === 'customRow') {
if (props.lineSelection && props.rowSelection) {
// customRow
renderProps[k] = (record, index) => {
return {
...(typeof props.customRow !== 'undefined' && props.customRow(record, index)),
onClick: (event) => {
// onClick
typeof data[k] !== 'undefined' &&
typeof data[k](record, index).onClick !== 'undefined' &&
data[k](record, index).onClick(event)
// disabled
const rowDisabled =
typeof props.rowSelection.getCheckboxProps !== 'undefined' &&
props.rowSelection.getCheckboxProps(record).disabled
if (rowDisabled) return
//
const classList = event.target?.classList
if (!classList.contains('ant-table-cell')) return
const key = (typeof props.rowKey === 'function' && props.rowKey(record)) || props.rowKey || index
let selectedRows = props.rowSelection.selectedRows
let selectedRowKeys = props.rowSelection.selectedRowKeys
const rowType = props.rowSelection?.type || 'checkbox'
if (rowType === 'radio' || props.rowSelection.selectedRowKeys === undefined) {
selectedRowKeys = [key]
selectedRows = [record]
} else if (!props.rowSelection.selectedRowKeys?.includes(key)) {
selectedRowKeys.push(key)
selectedRows.push(record)
} else {
const index = props.rowSelection.selectedRowKeys?.findIndex((itemKey) => itemKey === key)
selectedRows.splice(index, 1)
selectedRowKeys.splice(index, 1)
}
updateSelect(selectedRowKeys, selectedRows)
}
}
}
return renderProps[k]
}
}
renderProps[k] = props[k]
})
renderProps = {
...renderProps,
size: data.customSize, // sizea-tablecompSize
columns: data.columnsSetting.filter((value) => value.checked === undefined || value.checked),
...data.localSettings
}
// undefined null tableprops
renderTableProps.value = Object.entries(renderProps).reduce((x, [y, z]) => (z == null ? x : ((x[y] = z), x)), {})
console.log(renderTableProps.value, 'renderTableProps.value')
}
// total
const updateSelect = (selectedRowKeys, selectedRows) => {
if (props.rowSelection) {
// eslint-disable-next-line vue/no-mutating-props
props.rowSelection.selectedRows = selectedRows
// eslint-disable-next-line vue/no-mutating-props
props.rowSelection.selectedRowKeys = selectedRowKeys
// props.rowSelection.onChange(selectedRowKeys, selectedRows)
getTableProps()
}
const list = data.needTotalList
data.needTotalList = list.map((item) => {
return {
...item,
total: selectedRows.reduce((sum, val) => {
return addNumbers(sum, get(val, item.dataIndex))
}, 0)
}
})
}
// needTotal
const addNumbers = (num1, num2) => {
//
let num1Value = Number(num1)
let num2Value = Number(num2)
// 0
if (isNaN(num1Value)) {
num1Value = 0
}
if (isNaN(num2Value)) {
num2Value = 0
}
//
const num1DecimalPlaces = ('' + num1Value).split('.')[1] ? ('' + num1Value).split('.')[1].length : 0
const num2DecimalPlaces = ('' + num2Value).split('.')[1] ? ('' + num2Value).split('.')[1].length : 0
const decimalPlaces = Math.max(num1DecimalPlaces, num2DecimalPlaces)
// 10使10
return (
(Math.round(num1Value * Math.pow(10, decimalPlaces)) + Math.round(num2Value * Math.pow(10, decimalPlaces))) /
Math.pow(10, decimalPlaces)
)
}
// table
const clearSelected = () => {
if (props.rowSelection) {
props.rowSelection.onChange([], [])
updateSelect([], [])
getTableProps()
}
}
//
const clearRefreshSelected = (bool = false) => {
refresh(bool)
clearSelected()
}
//
defineExpose({
clearRefreshSelected,
refresh,
clearSelected
})
const isEditable = (column) => {
return column?.editable
}
const getEditorComponent = (column) => {
if (column.editorType) {
return column.editorType
}
return 'a-input' return 'a-input'
} }
const onCellChange = (record, column) => {
//
} }
// const saveChanges = () => {
const computedColumns = computed(() => { // emit('save', Object.values(data.editableData))
return props.columns.map((col) => ({ }
...col,
editable: col.editable
}))
})
const addRow = () => { const cancelChanges = () => {
const newRow = { initEditableData()
[props.rowKey]: Date.now().toString(), }
...props.columns.reduce((acc, col) => {
if (col.dataIndex) acc[col.dataIndex] = '' const initEditableData = () => {
data.editableData = data.localDataSource.reduce((acc, record) => {
acc[record.key] = { ...record }
return acc return acc
}, {}) }, {})
} }
dataSource.value = [...dataSource.value, newRow] onMounted(() => {
edit(newRow[props.rowKey]) init()
} // initEditableData()
})
const deleteRow = (key) => {
dataSource.value = dataSource.value.filter((item) => item[props.rowKey] !== key)
}
const handleFieldChange = (key, field, value) => {
dataSource.value = dataSource.value.map((item) => (item[props.rowKey] === key ? { ...item, [field]: value } : item))
}
const isEditing = (record) => record[props.rowKey] === editingKey.value
const edit = (key) => {
editingKey.value = key
}
const save = () => {
editingKey.value = null
}
const cancel = () => {
editingKey.value = null
}
const handleTableChange = (pagination, filters, sorter) => {
console.log('Table changed:', pagination, filters, sorter)
}
const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => {
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows)
},
onSelect: (record, selected, selectedRows) => {
console.log(record, selected, selectedRows)
},
onSelectAll: (selected, selectedRows, changeRows) => {
console.log(selected, selectedRows, changeRows)
}
}
</script> </script>
<style lang="less" scoped>
<style scoped> .s-table-tool {
.table-wrapper { display: flex;
margin: 16px;
}
.table-tool {
margin-bottom: 16px; margin-bottom: 16px;
.s-table-tool-left {
flex: 1;
}
.s-table-tool-right {
.s-tool-item {
font-size: 16px;
@apply ml-4;
cursor: pointer;
}
}
} }
</style> </style>

View File

@ -147,6 +147,7 @@
:rowClassName=" :rowClassName="
(record, index) => (data.localSettings.rowClassNameSwitch ? ((index + 1) % 2 == 0 ? 'odd' : '') : null) (record, index) => (data.localSettings.rowClassNameSwitch ? ((index + 1) % 2 == 0 ? 'odd' : '') : null)
" "
:scroll="{ x: '100%' }"
> >
<template #[item]="scope" v-for="item in renderSlots"> <template #[item]="scope" v-for="item in renderSlots">
<slot <slot
@ -669,4 +670,6 @@
} }
} }
} }
</style> </style>

View File

@ -43,12 +43,12 @@ export function useTableManagement(apiModule = {}, tableColumns, hasPermData, is
// 判断columns 是否有操作 // 判断columns 是否有操作
const columnsFilter = columns.value.filter((item) => item.dataIndex === 'action') const columnsFilter = columns.value.filter((item) => item.dataIndex === 'action')
if (columnsFilter.length === 0 && isShowAction) if (columnsFilter.length === 0 && isShowAction)
columns.value.unshift({ columns.value.push({
title: '操作', title: '操作',
dataIndex: 'action', dataIndex: 'action',
align: 'center', align: 'center',
width: 150, width: 160,
fixed: 'left' fixed: 'right'
}) })
} }

View File

@ -1,6 +1,8 @@
import { createApp } from 'vue' import { createApp } from 'vue'
import Antd from 'ant-design-vue' import Antd from 'ant-design-vue'
import { createPinia } from 'pinia' import { createPinia } from 'pinia'
// import STable from '@shene/table'
// import '@shene/table/dist/index.css'
import './style/index.less' import './style/index.less'
import snowy from './snowy' import snowy from './snowy'
@ -15,6 +17,7 @@ app.use(router)
app.use(Antd) app.use(Antd)
app.use(i18n) app.use(i18n)
app.use(snowy) app.use(snowy)
// app.use(STable)
// 挂载app // 挂载app
app.mount('#app') app.mount('#app')

View File

@ -363,7 +363,7 @@ body,
.gen-preview-content, .gen-preview-content,
.ant-menu, .ant-menu,
.ant-tabs-dropdown-menu, .ant-tabs-dropdown-menu,
.xn-table, .xs-table,
.selector-table, .selector-table,
.card-div, .card-div,
.ant-table-body, .ant-table-body,

View File

@ -0,0 +1,136 @@
<template>
<div class="wrap flex">
<div class="sider">
<iphone></iphone>
</div>
<div class="content">
<a-tabs v-model:activeKey="activeKey" type="card">
<a-tab-pane key="1" tab="基本配置">Content of Tab Pane 1</a-tab-pane>
<a-tab-pane key="2" tab="轮播图" force-render>
<a-upload
v-model:file-list="fileList"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
list-type="picture-card"
@preview="handlePreview"
>
<div v-if="fileList.length < 8">
<plus-outlined />
<div style="margin-top: 8px">Upload</div>
</div>
</a-upload>
<a-modal :open="previewVisible" :title="previewTitle" :footer="null" @cancel="handleCancel">
<img alt="example" style="width: 100%" :src="previewImage" />
</a-modal>
</a-tab-pane>
<a-tab-pane key="3" tab="产品验证正防伪信息">Content of Tab Pane 3</a-tab-pane>
<a-tab-pane key="4" tab="溯源流程">Content of Tab Pane 3</a-tab-pane>
<a-tab-pane key="5" tab="产品介绍">
<XnEditor></XnEditor>
</a-tab-pane>
<a-tab-pane key="6" tab="超链接">Content of Tab Pane 3</a-tab-pane>
</a-tabs>
</div>
</div>
</template>
<script setup>
// const props = defineProps({})
// const emit = defineEmits()
//
import Iphone from '@/views/productionBusiness/basicData/brand/counterfeiting/iphone.vue'
const siderStyle = {
color: '#fff',
backgroundColor: '#fff',
width: '350'
}
let activeKey = ref('5')
onMounted(() => {
console.log('Component mounted')
// TODO: Add your onMounted code here
})
onUpdated(() => {
console.log('Component updated')
// TODO: Add your onUpdated code here
})
onUnmounted(() => {
console.log('Component unmounted')
// TODO: Add your onUnmounted code here
})
// watch(() => {}, () => {})
function getBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result)
reader.onerror = (error) => reject(error)
})
}
const previewVisible = ref(false)
const previewImage = ref('')
const previewTitle = ref('')
const fileList = ref([
{
uid: '-1',
name: 'image.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
},
{
uid: '-2',
name: 'image.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
},
{
uid: '-3',
name: 'image.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
},
{
uid: '-4',
name: 'image.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
},
])
const handleCancel = () => {
previewVisible.value = false
previewTitle.value = ''
}
const handlePreview = async (file) => {
if (!file.url && !file.preview) {
file.preview = await getBase64(file.originFileObj)
}
previewImage.value = file.url || file.preview
previewVisible.value = true
previewTitle.value = file.name || file.url.substring(file.url.lastIndexOf('/') + 1)
}
</script>
<style scoped lang="less">
.wrap {
background: #ffffff;
padding: 30px;
.sider {
width: 460px;
position: relative;
height: 680px;
}
.content {
margin-left: 20px;
width: 100%;
}
}
</style>

View File

@ -0,0 +1,133 @@
<template>
<div>
<div class="iphone"></div>
<div class="iphone-content">
<div class="iphone-content-bg">
<img src="@/assets/images/h5_bg.jpg" alt="北京图" class="h5_bg" />
</div>
<div class="container">
<div class="container-logo">
<img src="@/assets/images/h5_logo.jpg" alt="logo" />
</div>
<div class="container-box">
<h3 class="container-box-title">产品信息</h3>
<p class="container-box-desc">产品名称莫个葡萄红酒</p>
<p class="container-box-desc">产品名称莫个葡萄红酒</p>
<p class="container-box-desc">产品名称莫个葡萄红酒</p>
</div>
<div class="container-box">
<h3 class="container-box-title">防伪查询结果</h3>
<h3>您所查询的122064588954755为官方正品</h3>
</div>
<div class="container-box">
<h3 class="container-box-title">溯源记录</h3>
<p class="container-box-desc">产品名称莫个葡萄红酒</p>
<p class="container-box-desc">产品名称莫个葡萄红酒</p>
<p class="container-box-desc">产品名称莫个葡萄红酒</p>
</div>
</div>
</div>
</div>
</template>
<script setup>
// const props = defineProps({})
// const emit = defineEmits()
//
onMounted(() => {
console.log('Component mounted')
// TODO: Add your onMounted code here
})
onUpdated(() => {
console.log('Component updated')
// TODO: Add your onUpdated code here
})
onUnmounted(() => {
console.log('Component unmounted')
// TODO: Add your onUnmounted code here
})
// watch(() => {}, () => {})
</script>
<style scoped lang="less">
.iphone {
font-size: 16px;
background-color: #fff;
width: 330px;
position: absolute;
z-index: 10;
margin: 0;
top: 0;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
background-image: url('@/assets/images/iPhone13.png');
background-repeat: no-repeat;
background-size: 100%;
border-radius: 30px;
padding: 48px 13px 25px;
height: 100%;
}
.iphone-content {
width: 330px;
box-sizing: border-box;
height: 100%;
border-bottom-left-radius: 30px;
overflow: hidden;
padding: 48px 13px 25px;
&-bg {
position: absolute;
padding: 48px 13px 25px;
width: 330px;
height: 100%;
left: 0;
top: 0;
z-index: 100;
.h5_bg {
width: 100%;
height: 100%;
border-radius: 0 0 30px 30px;
}
}
.container {
position: relative;
z-index: 101;
top: 0;
&-logo {
text-align: center;
img {
width: 150px;
height: 150px;
}
}
&-box {
background: rgba(255, 255, 255, 0.8);
padding: 10px;
margin: 0 15px 15px;
border-radius: 5px;
}
}
}
:deep(.slick-slide) {
text-align: center;
height: 160px;
line-height: 160px;
background: #364d79;
overflow: hidden;
}
:deep(.slick-slide h3) {
color: #fff;
}
</style>

View File

@ -5,6 +5,17 @@
</template> </template>
</a-page-header> </a-page-header>
<a-button
type="primary"
@click="
navigateTo('/brand/counterfeiting', {
type: 'ADD'
})
"
>
防伪页面
</a-button>
<a-card :bordered="false" title="品牌"> <a-card :bordered="false" title="品牌">
<DynamicForm <DynamicForm
:allDisabled="route.query.type === 'SEARCH'" :allDisabled="route.query.type === 'SEARCH'"
@ -41,6 +52,8 @@
import useFormHandler from '@/hook/useFormHandler' import useFormHandler from '@/hook/useFormHandler'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { brandFormItems, formRules } from '@/views/productionBusiness/basicData/brand/formFields/detailFields' import { brandFormItems, formRules } from '@/views/productionBusiness/basicData/brand/formFields/detailFields'
import { useNavigation } from '@/hook/useNavigation'
const { navigateTo } = useNavigation()
const route = useRoute() const route = useRoute()
const formRef1 = ref(null) const formRef1 = ref(null)

View File

@ -51,7 +51,6 @@
</template> </template>
<template v-if="column.dataIndex === 'action'"> <template v-if="column.dataIndex === 'action'">
<a-space> <a-space>
<a-tooltip title="查看">
<a <a
@click=" @click="
navigateTo('/basicData/brand/detail', { navigateTo('/basicData/brand/detail', {
@ -62,33 +61,49 @@
v-if="hasPerm('customerEdit')" v-if="hasPerm('customerEdit')"
> >
<EyeOutlined /> <EyeOutlined />
<!-- 查看--> 查看
</a> </a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" /> <a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-tooltip title="编辑">
<a <a-dropdown>
<a class="ant-dropdown-link" @click.prevent>
更多
<DownOutlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item>
<a-button
type="link"
size="small"
@click=" @click="
navigateTo('/basicData/brand/detail', { navigateTo('/basicData/brand/detail', {
type: 'EDIT', type: 'EDIT',
id: record.id id: record.id
}) })
" "
v-if="hasPerm('customerEdit')" v-if="hasPerm('sysUnitEdit')"
> >
<FormOutlined /> <FormOutlined />
<!-- 编辑--> 编辑
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">
<DeleteOutlined />
<!-- 删除-->
</a-button> </a-button>
</a-popconfirm> </a-menu-item>
<a-menu-item>
<a-button
type="link"
danger
size="small"
v-if="hasPerm('materialDelete')"
@click="deleteRecord(record)"
>
<DeleteOutlined />
删除
</a-button>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space> </a-space>
</template> </template>
</template> </template>

View File

@ -77,7 +77,6 @@
</template> </template>
<template v-if="column.dataIndex === 'action'"> <template v-if="column.dataIndex === 'action'">
<a-space> <a-space>
<a-tooltip title="查看">
<a <a
@click=" @click="
navigateTo('/basicData/client/detail', { navigateTo('/basicData/client/detail', {
@ -88,32 +87,48 @@
v-if="hasPerm('customerEdit')" v-if="hasPerm('customerEdit')"
> >
<EyeOutlined /> <EyeOutlined />
<!-- 查看--> 查看
</a> </a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" /> <a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-tooltip title="编辑"> <a-dropdown>
<a <a class="ant-dropdown-link" @click.prevent>
更多
<DownOutlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item>
<a-button
type="link"
size="small"
@click=" @click="
navigateTo('/basicData/client/detail', { navigateTo('/basicData/client/detail', {
type: 'EDIT', type: 'EDIT',
id: record.id id: record.id
}) })
" "
v-if="hasPerm('customerEdit')" v-if="hasPerm('sysUnitEdit')"
> >
<FormOutlined /> <FormOutlined />
<!-- 编辑--> 编辑
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">
<DeleteOutlined />
</a-button> </a-button>
</a-popconfirm> </a-menu-item>
<a-menu-item>
<a-button
type="link"
danger
size="small"
v-if="hasPerm('materialDelete')"
@click="deleteRecord(record)"
>
<DeleteOutlined />
删除
</a-button>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space> </a-space>
</template> </template>
</template> </template>

View File

@ -77,7 +77,6 @@
</template> </template>
<template v-if="column.dataIndex === 'action'"> <template v-if="column.dataIndex === 'action'">
<a-space> <a-space>
<a-tooltip title="查看">
<a <a
@click=" @click="
navigateTo('/basicData/materiel/detail', { navigateTo('/basicData/materiel/detail', {
@ -88,32 +87,48 @@
v-if="hasPerm('materialEdit')" v-if="hasPerm('materialEdit')"
> >
<EyeOutlined /> <EyeOutlined />
<!-- 查看--> 查看
</a> </a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['materialEdit', 'materialDelete'], 'and')" /> <a-divider type="vertical" v-if="hasPerm(['materialEdit', 'materialDelete'], 'and')" />
<a-tooltip title="编辑">
<a <a-dropdown>
<a class="ant-dropdown-link" @click.prevent>
更多
<DownOutlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item>
<a-button
type="link"
size="small"
@click=" @click="
navigateTo('/basicData/materiel/detail', { navigateTo('/basicData/materiel/detail', {
type: 'EDIT', type: 'EDIT',
id: record.id id: record.id
}) })
" "
v-if="hasPerm('materialEdit')" v-if="hasPerm('sysUnitEdit')"
> >
<FormOutlined /> <FormOutlined />
<!-- 编辑--> 编辑
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['materialEdit', 'materialDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('materialDelete')">
<DeleteOutlined />
<!-- 删除-->
</a-button> </a-button>
</a-popconfirm> </a-menu-item>
<a-menu-item>
<a-button
type="link"
danger
size="small"
v-if="hasPerm('materialDelete')"
@click="deleteRecord(record)"
>
<DeleteOutlined />
删除
</a-button>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space> </a-space>
</template> </template>
</template> </template>

View File

@ -42,8 +42,8 @@
</a-space> </a-space>
</template> </template>
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'number'"> <template v-if="column.dataIndex === 'type'">
<span style="color: #0d84ff">{{ record.number }}</span> <span style="color: #0d84ff">{{ $TOOL.dictTypeData('OFFICIAL_ACCOUNT_TYPE', record.type) }}</span>
</template> </template>
<template v-if="column.dataIndex === 'enabledState'"> <template v-if="column.dataIndex === 'enabledState'">
<a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag> <a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag>
@ -51,7 +51,6 @@
</template> </template>
<template v-if="column.dataIndex === 'action'"> <template v-if="column.dataIndex === 'action'">
<a-space> <a-space>
<a-tooltip title="查看">
<a <a
@click=" @click="
navigateTo('/basicData/publicAccount/detail', { navigateTo('/basicData/publicAccount/detail', {
@ -62,33 +61,47 @@
v-if="hasPerm('customerEdit')" v-if="hasPerm('customerEdit')"
> >
<EyeOutlined /> <EyeOutlined />
<!-- 查看--> 查看
</a> </a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" /> <a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-tooltip title="编辑"> <a-dropdown>
<a <a class="ant-dropdown-link" @click.prevent>
更多
<DownOutlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item>
<a-button
type="link"
size="small"
@click=" @click="
navigateTo('/basicData/publicAccount/detail', { navigateTo('/basicData/publicAccount/detail', {
type: 'EDIT', type: 'EDIT',
id: record.id id: record.id
}) })
" "
v-if="hasPerm('customerEdit')" v-if="hasPerm('sysUnitEdit')"
> >
<FormOutlined /> <FormOutlined />
<!-- 编辑--> 编辑
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">
<DeleteOutlined />
<!-- 删除-->
</a-button> </a-button>
</a-popconfirm> </a-menu-item>
<a-menu-item>
<a-button
type="link"
danger
size="small"
v-if="hasPerm('materialDelete')"
@click="deleteRecord(record)"
>
<DeleteOutlined />
删除
</a-button>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space> </a-space>
</template> </template>
</template> </template>

View File

@ -72,7 +72,6 @@
</template> </template>
<template v-if="column.dataIndex === 'action'"> <template v-if="column.dataIndex === 'action'">
<a-space> <a-space>
<a-tooltip title="查看">
<a <a
@click=" @click="
navigateTo('/basicData/stash/detail', { navigateTo('/basicData/stash/detail', {
@ -83,33 +82,47 @@
v-if="hasPerm('customerEdit')" v-if="hasPerm('customerEdit')"
> >
<EyeOutlined /> <EyeOutlined />
<!-- 查看--> 查看
</a> </a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" /> <a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-tooltip title="编辑"> <a-dropdown>
<a <a class="ant-dropdown-link" @click.prevent>
更多
<DownOutlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item>
<a-button
type="link"
size="small"
@click=" @click="
navigateTo('/basicData/stash/detail', { navigateTo('/basicData/stash/detail', {
type: 'EDIT', type: 'EDIT',
id: record.id id: record.id
}) })
" "
v-if="hasPerm('customerEdit')" v-if="hasPerm('sysUnitEdit')"
> >
<FormOutlined /> <FormOutlined />
<!-- 编辑--> 编辑
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">
<DeleteOutlined />
<!-- 删除-->
</a-button> </a-button>
</a-popconfirm> </a-menu-item>
<a-menu-item>
<a-button
type="link"
danger
size="small"
v-if="hasPerm('materialDelete')"
@click="deleteRecord(record)"
>
<DeleteOutlined />
删除
</a-button>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space> </a-space>
</template> </template>
</template> </template>

View File

@ -74,25 +74,45 @@
</template> </template>
<template v-if="column.dataIndex === 'action'"> <template v-if="column.dataIndex === 'action'">
<a-space> <a-space>
<a-tooltip title="查看">
<a @click="TissueFormRef.onOpen({ ...record, pageType: 'SEARCH' })"> <a @click="TissueFormRef.onOpen({ ...record, pageType: 'SEARCH' })">
<EyeOutlined /> <EyeOutlined />
查看
</a> </a>
</a-tooltip>
<a-divider type="vertical" /> <a-divider type="vertical" />
<a-tooltip title="编辑"> <a-dropdown>
<a @click="TissueFormRef.onOpen({ ...record, pageType: 'EDIT' })"> <a class="ant-dropdown-link" @click.prevent>
更多
<DownOutlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item>
<a-button
type="link"
size="small"
@click="TissueFormRef.onOpen({ ...record, pageType: 'EDIT' })"
v-if="hasPerm('sysUnitEdit')"
>
<FormOutlined /> <FormOutlined />
</a> 编辑
</a-tooltip>
<a-divider type="vertical" />
<a-popconfirm title="确定要删除吗?" @confirm="handleConfirmDeleteRecord(record)">
<a-button type="link" danger size="small">
<DeleteOutlined />
</a-button> </a-button>
</a-popconfirm> </a-menu-item>
<a-menu-item>
<a-button
type="link"
danger
size="small"
v-if="hasPerm('materialDelete')"
@click="handleConfirmDeleteRecord(record)"
>
<DeleteOutlined />
删除
</a-button>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space> </a-space>
</template> </template>
</template> </template>

View File

@ -1,4 +1,11 @@
export const unitColumns = [ export const unitColumns = [
{
title: '序号',
dataIndex: 'index',
width: 80,
resizable: true,
align: 'center'
},
{ {
title: '编码', title: '编码',
dataIndex: 'number', dataIndex: 'number',
@ -52,6 +59,13 @@ export const unitColumns = [
] ]
export const unitGroupColumns = [ export const unitGroupColumns = [
{
title: '序号',
dataIndex: 'index',
width: 80,
resizable: true,
align: 'center'
},
{ {
title: '名称', title: '名称',
dataIndex: 'name', dataIndex: 'name',

View File

@ -29,7 +29,10 @@
<template #operator> <template #operator>
<span>单位组</span> <span>单位组</span>
</template> </template>
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record, index}">
<template v-if="column.dataIndex === 'index'">
<span>{{ index + 1 }}</span>
</template>
<template v-if="column.dataIndex === 'enabledState'"> <template v-if="column.dataIndex === 'enabledState'">
<a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag> <a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag>
<a-tag color="#f50" v-if="record.enabledState === 'DISABLED'"></a-tag> <a-tag color="#f50" v-if="record.enabledState === 'DISABLED'"></a-tag>
@ -73,7 +76,10 @@
/> />
</a-space> </a-space>
</template> </template>
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'index'">
<span>{{ index + 1 }}</span>
</template>
<template v-if="column.dataIndex === 'number'"> <template v-if="column.dataIndex === 'number'">
<span style="color: #0d84ff">{{ record.number }}</span> <span style="color: #0d84ff">{{ record.number }}</span>
</template> </template>
@ -86,7 +92,6 @@
</template> </template>
<template v-if="column.dataIndex === 'action'"> <template v-if="column.dataIndex === 'action'">
<a-space> <a-space>
<a-tooltip title="查看">
<a <a
@click=" @click="
navigateTo('/basicData/unit/detail', { navigateTo('/basicData/unit/detail', {
@ -97,12 +102,21 @@
v-if="hasPerm('sysUnitEdit')" v-if="hasPerm('sysUnitEdit')"
> >
<EyeOutlined /> <EyeOutlined />
<!-- 查看--> 查看
</a> </a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['sysUnitEdit', 'sysUnitDelete'], 'and')" /> <a-divider type="vertical" v-if="hasPerm(['sysUnitEdit', 'sysUnitDelete'], 'and')" />
<a-tooltip title="编辑">
<a <a-dropdown>
<a class="ant-dropdown-link" @click.prevent>
更多
<DownOutlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item>
<a-button
type="link"
size="small"
@click=" @click="
navigateTo('/basicData/unit/detail', { navigateTo('/basicData/unit/detail', {
type: 'EDIT', type: 'EDIT',
@ -112,16 +126,24 @@
v-if="hasPerm('sysUnitEdit')" v-if="hasPerm('sysUnitEdit')"
> >
<FormOutlined /> <FormOutlined />
<!-- 编辑--> 编辑
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['sysUnitEdit', 'sysUnitDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('sysUnitDelete')">
<DeleteOutlined />
<!-- 删除-->
</a-button> </a-button>
</a-popconfirm> </a-menu-item>
<a-menu-item>
<a-button
type="link"
danger
size="small"
@click="deleteRecord(record)"
v-if="hasPerm('sysUnitEdit')"
>
<DeleteOutlined />
删除
</a-button>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space> </a-space>
</template> </template>
</template> </template>

View File

@ -0,0 +1,240 @@
<template>
<a-card class="mt-4" :bordered="false" title="产码配置">
<s-table
ref="tableRef"
:columns="columns"
:data="loadData"
:alert="options.alert.show"
bordered
:row-key="(record) => record.id"
:tool-config="options.toolConfig"
:scroll="{
x: '100%'
}"
>
<template #operator>
<a-space>
<a-button type="primary" @click="codeElementFormRef.onOpen()">
<template #icon><plus-outlined /></template>
新增
</a-button>
</a-space>
</template>
<template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'index'">
{{ index + 1 }}
</template>
<template v-if="column.dataIndex === 'barcodeValue'">
{{ $TOOL.dictTypeData('MATERIAL_PACKAGE_TYPE', record.barcodeValue) }}
</template>
<template v-if="column.dataIndex === 'action'">
<a-space>
<a @click="codeElementFormRef.onOpen({ ...record, pageType: 'SEARCH' })">
<EyeOutlined />
查看
</a>
<a-divider type="vertical" />
<a-dropdown>
<a class="ant-dropdown-link" @click.prevent>
更多
<DownOutlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item>
<a-button
type="link"
size="small"
@click="codeElementFormRef.onOpen({ ...record, pageType: 'EDIT' })"
v-if="hasPerm('sysUnitEdit')"
>
<FormOutlined />
编辑
</a-button>
</a-menu-item>
<a-menu-item>
<a-button type="link" size="small" @click="handleOpenModal(record, { elementType: 1 })"
>条码元素</a-button
>
</a-menu-item>
<a-menu-item>
<a-button type="link" size="small" @click="handleOpenModal(record, { elementType: 2 })"
>内码元素</a-button
>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space>
</template>
</template>
</s-table>
</a-card>
<a-modal v-model:open="open" title="元素配置" width="900px" @ok="handleModalOk" class="modal">
<div style="height: 500px">
<DynamicTable
:scroll="{
x: '100%',
y: 350
}"
:dataSource="codeElementData"
:columns="codeElementColumn"
>
<template #operator>
<a-button type="primary" @click="handleCodeElement">
<template #icon><plus-outlined /></template>
新增
</a-button>
</template>
<template #action="{ record, index }">
<a-space>
<a type="link" @click="handleUp(index)">
<ArrowUpOutlined />
上移
</a>
<a type="link" @click="handleDown(index)"> <ArrowDownOutlined />下移 </a>
<a style="color: red" type="link" @click="handleDel(record, index)"><DeleteOutlined /> 删除 </a>
</a-space>
</template>
</DynamicTable>
</div>
</a-modal>
<code-element-form ref="codeElementFormRef" @successful="successful"></code-element-form>
</template>
<script setup>
import { codeElementColumn, codeProduction } from '@/views/productionBusiness/control/codeOrigin/columns/columns'
import CodeElementForm from '@/views/productionBusiness/control/codeOrigin/detail/codeElementForm.vue'
import { useTableManagement } from '@/hook/useTableManagement'
import productCodeConfigApi from '@/api/production/productcode/productCodeConfigApi'
import productCodeConfigElementApi from '@/api/production/productcode/productCodeConfigElementApi'
import { message } from 'ant-design-vue'
const codeElementFormRef = ref(null)
const { searchFormState, tableRef, selectedRowKeys, columns, loadData, deleteBatchRecords, options, deleteRecord } =
useTableManagement(
{
page: productCodeConfigApi.productCodeConfigPage,
delete: productCodeConfigApi.productCodeConfigDelete
},
codeProduction,
['materialEdit', 'materialDelete']
)
const successful = () => {
tableRef.value.refresh()
}
//
onMounted(async () => {})
let open = ref(false)
let codeElementItem = {}
const handleOpenModal = (record, params) => {
open.value = true
codeElementItem = { ...record, ...params }
productCodeConfigElementApi
.productCodeConfigElementList({ productCodeConfigId: record.id, elementType: params.elementType })
.then((res) => {
codeElementData.value = res.records || []
})
}
let codeElementData = ref([])
const handleCodeElement = () => {
let newObjItem = {}
codeElementColumn.forEach((item) => {
newObjItem[item.dataIndex] = null
})
codeElementData.value.push(newObjItem)
}
const handleUp = (index) => {
if (index === 0) return //
const temp = codeElementData.value[index - 1]
codeElementData.value[index - 1] = codeElementData.value[index]
codeElementData.value[index] = temp
}
const handleDown = (index) => {
if (index === codeElementData.value.length - 1) return //
const temp = codeElementData.value[index + 1]
codeElementData.value[index + 1] = codeElementData.value[index]
codeElementData.value[index] = temp
}
const handleDel = (record, index) => {
if (record.id) {
productCodeConfigElementApi
.productCodeConfigElementDelete([
{
id: record.id
}
])
.then((res) => {
codeElementData.value.splice(index, 1)
})
} else {
codeElementData.value.splice(index, 1)
}
}
const handleModalOk = () => {
console.log(codeElementItem)
if (codeElementData.value.length === 0) return message.error('请添加元素')
if (codeElementData.value.length < 2) return message.error('元素规则必须大于2条')
for (let i = 0; i < codeElementData.value.length; i++) {
if (
!codeElementData.value[i].elementLength ||
!codeElementData.value[i].elementValue ||
!codeElementData.value[i].productCodeRule
)
return message.error('请完善元素信息')
}
let count = 0
codeElementData.value.forEach((item) => {
count += item.elementLength
})
if (codeElementItem.barcodeLength && codeElementItem.elementType === 1 && count !== codeElementItem.barcodeLength)
return message.error('元素所加长度与条码长度不符合')
if (
codeElementItem.barcodeInteriorLength &&
codeElementItem.elementType === 2 &&
count !== codeElementItem.barcodeInteriorLength
)
return message.error('元素所加长度与内码长度不符合')
productCodeConfigElementApi
.productCodeConfigElementBatchSave(
codeElementData.value.map((item) => {
return {
productCodeConfigId: codeElementItem.id,
elementType: codeElementItem.elementType,
...item
}
})
)
.then((res) => {
message.success('操作成功')
open.value = false
})
}
onUpdated(() => {})
onUnmounted(() => {})
// watch(() => {}, () => {})
</script>
<style scoped></style>

View File

@ -0,0 +1,214 @@
import tool from '@/utils/tool'
export const codeProduction = [
{
title: '序号',
dataIndex: 'index',
width: 80,
resizable: true,
align: 'center'
},
{
title: '条码类型',
dataIndex: 'barcodeValue',
width: 240,
resizable: true,
align: 'center'
},
{
title: '条码长度',
dataIndex: 'barcodeLength',
width: 240,
editable: true,
resizable: true,
align: 'center'
},
{
title: '内码长度',
dataIndex: 'barcodeInteriorLength',
width: 240,
editable: true,
resizable: true,
align: 'center'
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
width: 160,
fixed: 'right'
}
]
export const packetColumn = [
{
title: '序号',
dataIndex: 'index',
width: 80,
align: 'center'
},
{
title: '码包配置名称',
dataIndex: 'name',
width: 160,
editable: true,
resizable: true,
align: 'center'
},
{
title: '条码类型',
dataIndex: 'productCodeConfigLabel',
width: 160,
editable: true,
editorType: 'a-select',
attrs: {
options: []
},
resizable: true,
align: 'center'
},
{
title: '导出格式',
dataIndex: 'exportFormat',
width: 160,
editable: true,
editorType: 'a-select',
attrs: {
options: []
},
resizable: true,
align: 'center'
},
{
title: '条码前缀',
dataIndex: 'barcodePrefix',
width: 160,
editable: true,
resizable: true,
align: 'center'
},
{
title: '内码前缀',
dataIndex: 'barcodeInteriorPrefix',
width: 160,
editable: true,
resizable: true,
align: 'center'
},
{
title: '导出格式示例',
dataIndex: 'exportFormatExample',
width: 160,
editable: true,
resizable: true,
align: 'center'
},
{
title: '操作',
dataIndex: 'action',
width: 160,
fixed: 'right',
align: 'center'
}
]
export const codeElementColumn = [
{
title: '序号',
dataIndex: 'index',
resizable: true,
width: 80,
align: 'center'
},
{
title: '码元素值',
dataIndex: 'elementValue',
width: 240,
editable: true,
editorType: 'a-input',
resizable: true,
align: 'center'
},
{
title: '元素长度',
dataIndex: 'elementLength',
width: 240,
editable: true,
editorType: 'a-input-number',
align: 'center',
resizable: true
},
{
title: '产码规则',
dataIndex: 'productCodeRule',
width: 240,
editable: true,
editorType: 'a-select',
attrs: {
options: tool.dictList('MYSGZ')
},
align: 'center',
resizable: true
},
/*{
title: '备注',
dataIndex: 'remarks',
width: 120,
align: 'center',
resizable: true
},*/
{
title: '操作',
dataIndex: 'action',
slot: 'action',
width: 200,
align: 'center',
resizable: true,
fixed: 'right'
}
]
export const regionColumn = [
{
title: '产码生成数量',
dataIndex: 'exportNumber',
align: 'center',
resizable: true,
width: 300,
ellipsis: true
},
{
title: '下载次数',
dataIndex: 'downloadCount',
align: 'center',
resizable: true,
width: 300,
ellipsis: true
},
{
title: '最后一次下载时间',
dataIndex: 'downloadTime',
align: 'center',
resizable: true,
width: 300,
ellipsis: true
},
{
title: '创建人',
dataIndex: 'createUserName',
align: 'center',
resizable: true,
width: 300,
ellipsis: true
},
{
title: '创建时间',
dataIndex: 'createTime',
sorter: true,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
width: 300,
ellipsis: true
}
]

View File

@ -0,0 +1,75 @@
<template>
<xn-form-container
:title="formData.id ? '编辑单位组' : '增加单位组'"
:width="700"
:visible="visible"
:destroy-on-close="true"
@close="onClose"
>
<DynamicForm :formItems="codeElementFormFields" :model="formData" :rules="formRules" ref="formRef1" />
<OperationalInformation :detailData="recordData" :colSpan="12" v-if="recordData.id"></OperationalInformation>
<template #footer>
<a-button style="margin-right: 8px" @click="onClose"></a-button>
<a-button type="primary" @click="onSubmitForm"></a-button>
</template>
</xn-form-container>
</template>
<script setup name="sysUnitGroupForm">
import { cloneDeep } from 'lodash-es'
import { codeElementFormFields, formRules } from '@/views/productionBusiness/control/codeOrigin/formFields/drawerForm'
import useFormHandler from '@/hook/useFormHandler'
import productCodeConfigApi from '@/api/production/productcode/productCodeConfigApi'
import tool from '@/utils/tool'
//
const visible = ref(false)
const emit = defineEmits({ successful: null })
const formRef1 = ref(null)
let recordData = reactive({})
//
const onOpen = (record) => {
visible.value = true
nextTick(() => {
formRefs.value = [formRef1.value]
codeElementFormFields[0].attrs.onChange = (value) => {
formData.barcodeLabel = tool.dictTypeData('MATERIAL_PACKAGE_TYPE', value)
console.log(formData, 'formData')
}
})
if (record) {
recordData = cloneDeep(record)
fetchData().then(() => {
populateFormData(recordData)
})
} else {
fetchData()
recordData = {}
}
}
//
const onClose = () => {
visible.value = false
}
//
const onSubmitForm = () => {
onSubmit({
isEnable: true,
id: recordData.id
}).then(() => {
onClose()
emit('successful')
})
}
let { formData, onSubmit, populateFormData, fetchData, formRefs } = useFormHandler([...codeElementFormFields], {
submitForm: productCodeConfigApi.productCodeConfigSubmitForm
})
//
defineExpose({
onOpen
})
</script>

View File

@ -0,0 +1,78 @@
<template>
<xn-form-container
:title="formData.id ? '编辑单位组' : '增加单位组'"
:width="700"
:visible="visible"
:destroy-on-close="true"
@close="onClose"
>
<DynamicForm :formItems="packetConfigFormFields" :model="formData" :rules="formRules" ref="formRef1" />
<OperationalInformation :detailData="recordData" :colSpan="12" v-if="recordData.id"></OperationalInformation>
<template #footer>
<a-button style="margin-right: 8px" @click="onClose"></a-button>
<a-button type="primary" @click="onSubmitForm"></a-button>
</template>
</xn-form-container>
</template>
<script setup name="sysUnitGroupForm">
import { cloneDeep } from 'lodash-es'
import {
packetConfigFormFields,
formRules
} from '@/views/productionBusiness/control/codeOrigin/formFields/packetConfigForm'
import useFormHandler from '@/hook/useFormHandler'
import productCodeConfigApi from '@/api/production/productcode/productCodeConfigApi'
import productCodePackageConfigApi from '@/api/production/productcode/productCodePackageConfigApi'
//
const visible = ref(false)
const emit = defineEmits({ successful: null })
const formRef1 = ref(null)
let recordData = reactive({})
//
const onOpen = (record) => {
visible.value = true
nextTick(() => {
formRefs.value = [formRef1.value]
})
productCodeConfigApi.productCodeConfigList().then((res) => {
packetConfigFormFields[1].attrs.options = res
})
if (record) {
recordData = cloneDeep(record)
fetchData().then(() => {
populateFormData(recordData)
})
} else {
fetchData()
recordData = {}
}
}
//
const onClose = () => {
visible.value = false
}
//
const onSubmitForm = () => {
onSubmit({
isEnable: true,
id: recordData.id
}).then(() => {
onClose()
emit('successful')
})
}
let { formData, onSubmit, populateFormData, fetchData, formRefs } = useFormHandler([...packetConfigFormFields], {
submitForm: productCodePackageConfigApi.productCodePackageConfigSubmitForm
})
//
defineExpose({
onOpen
})
</script>

View File

@ -0,0 +1,41 @@
import tool from '@/utils/tool'
import { required } from '@/utils/formRules'
export const codeElementFormFields = reactive([
{
label: '条码类型:',
name: 'barcodeValue',
type: 'a-select',
span: 12,
attrs: {
placeholder: '请选择条码类型',
options: tool.dictList('MATERIAL_PACKAGE_TYPE')
}
},
{
label: '条码长度:',
name: 'barcodeLength',
type: 'a-input-number',
span: 12,
attrs: {
placeholder: '请输入条码长度',
allowClear: true
}
},
{
label: '内码长度:',
name: 'barcodeInteriorLength',
type: 'a-input-number',
span: 12,
attrs: {
placeholder: '请输入内码长度',
allowClear: true
}
}
])
export const formRules = {
barcodeValue: [required('请选择条码类型')],
barcodeInteriorLength: [required('请输入内码长度')],
barcodeLength: [required('请输入条码长度')],
}

View File

@ -0,0 +1,64 @@
import tool from '@/utils/tool'
import { required } from '@/utils/formRules'
export const packetConfigFormFields = reactive([
{
label: '码包配置名称:',
name: 'name',
type: 'a-input',
span: 12,
attrs: {
placeholder: '请输入码包配置名称'
}
},
{
label: '条码类型:',
name: 'productCodeConfigId',
type: 'a-select',
span: 12,
attrs: {
placeholder: '请选择条码类型',
options: [],
fieldNames: {
label: 'barcodeLabel',
value: 'id'
}
}
},
{
label: '导出格式:',
name: 'exportFormat',
type: 'a-select',
span: 12,
attrs: {
placeholder: '请选择导出格式',
options: tool.dictList('DCGS')
}
},
{
label: '条码前缀:',
name: 'barcodePrefix',
type: 'a-input',
span: 12,
attrs: {
placeholder: '请输入条码前缀',
allowClear: true
}
},
{
label: '内码前缀:',
name: 'barcodeInteriorPrefix',
type: 'a-input',
span: 12,
attrs: {
placeholder: '请输入内码前缀',
allowClear: true
}
}
])
export const formRules = {
name: [required('请输入码包配置名称')],
productCodeConfigId: [required('请选择条码类型')],
exportFormat: [required('请选择导出格式')]
}

View File

@ -0,0 +1,121 @@
<template>
<div>
<a-card class="mt-4" :bordered="false" title="码包配置">
<s-table
ref="tableRef"
:columns="columns"
:data="loadData"
:alert="options.alert.show"
bordered
:row-key="(record) => record.id"
:tool-config="options.toolConfig"
:scroll="{
x: 100
}"
>
<template #operator>
<a-space>
<a-button type="primary" @click="packetConfigFormRef.onOpen()">
<template #icon><plus-outlined /></template>
新增
</a-button>
</a-space>
</template>
<template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'index'">
{{ index + 1 }}
</template>
<template v-if="column.dataIndex === 'exportFormat'">
{{ $TOOL.dictTypeData('DCGS', record.exportFormat) }}
</template>
<template v-if="column.dataIndex === 'action'">
<a-space>
<a @click="packetConfigFormRef.onOpen({ ...record, pageType: 'SEARCH' })">
<EyeOutlined />
查看
</a>
<a-divider type="vertical" />
<a-dropdown>
<a class="ant-dropdown-link" @click.prevent>
更多
<DownOutlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item>
<a-button
type="link"
size="small"
@click="packetConfigFormRef.onOpen({ ...record, pageType: 'EDIT' })"
v-if="hasPerm('sysUnitEdit')"
>
<FormOutlined />
编辑
</a-button>
</a-menu-item>
<a-menu-item>
<a-button type="link" danger size="small" @click="deleteRecord(record)">
<DeleteOutlined />
删除
</a-button>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space>
</template>
</template>
</s-table>
</a-card>
</div>
<packet-config-form ref="packetConfigFormRef" @successful="successful"></packet-config-form>
</template>
<script setup>
// const props = defineProps({})
// const emit = defineEmits()
//
import { packetColumn } from '@/views/productionBusiness/control/codeOrigin/columns/columns'
import { useTableManagement } from '@/hook/useTableManagement'
import productCodePackageConfigApi from '@/api/production/productcode/productCodePackageConfigApi'
import PacketConfigForm from '@/views/productionBusiness/control/codeOrigin/detail/packetConfigForm.vue'
const packetConfigFormRef = ref(null)
const { searchFormState, tableRef, selectedRowKeys, columns, loadData, deleteBatchRecords, options, deleteRecord } =
useTableManagement(
{
page: productCodePackageConfigApi.productCodePackageConfigPage,
delete: productCodePackageConfigApi.productCodePackageConfigDelete
},
packetColumn,
['materialEdit', 'materialDelete']
)
const successful = () => {
tableRef.value.refresh()
}
onMounted(() => {
console.log('Component mounted')
// TODO: Add your onMounted code here
})
onUpdated(() => {
console.log('Component updated')
// TODO: Add your onUpdated code here
})
onUnmounted(() => {
console.log('Component unmounted')
// TODO: Add your onUnmounted code here
})
// watch(() => {}, () => {})
</script>
<style scoped></style>

View File

@ -0,0 +1,123 @@
<template>
<a-card :bordered="false">
<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
<a-row :gutter="24">
<a-col :span="6">
<a-form-item label="标签" name="number">
<a-input v-model:value="searchFormState.number" placeholder="请输入编码" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="编码" name="number">
<a-input v-model:value="searchFormState.number" placeholder="请输入编码" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="名称" name="name">
<a-input v-model:value="searchFormState.name" placeholder="请输入名称" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="可用状态" name="enabledState">
<a-select
v-model:value="searchFormState.enabledState"
placeholder="请选择可用状态"
:options="$TOOL.dictList('COMMON_STATUS')"
/>
</a-form-item>
</a-col>
<a-col :span="6">
<a-button type="primary" @click="tableRef.refresh()"></a-button>
<a-button style="margin: 0 8px" @click="reset"></a-button>
</a-col>
</a-row>
</a-form>
</a-card>
<a-card :bordered="false" class="mt-4" style="height: 100%">
<s-table
ref="tableRef"
:columns="columns"
:data="loadData"
bordered
:tool-config="options.toolConfig"
:scroll="{
x: 100
}"
>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'number'">
<span style="color: #1890ff">{{ record.number }}</span>
</template>
<template v-if="column.dataIndex === 'enabledState'">
<a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag>
<a-tag color="#f50" v-if="record.enabledState === 'DISABLED'"></a-tag>
</template>
<template v-if="column.dataIndex === 'action'">
<a-space>
<a @click="handleDownload(record)" v-if="hasPerm('customerEdit')">
<VerticalAlignBottomOutlined />
下载码包
</a>
</a-space>
</template>
</template>
</s-table>
</a-card>
</template>
<script setup name="records">
import { useTableManagement } from '@/hook/useTableManagement'
import { regionColumn } from '@/views/productionBusiness/control/codeOrigin/columns/columns'
import produceBarcodeHistoryApi from '@/api/production/productcode/produceBarcodeHistoryApi'
import { message, Modal } from 'ant-design-vue'
const tagModalRef = ref(null)
const handleOpenTag = (record) => {
tagModalRef.value.openModal(record)
}
const handleDownload = (record) => {
Modal.confirm({
title: '确认下载?',
content: '点击确认下载此条记录的码包',
onOk() {
console.log('OK')
produceBarcodeHistoryApi
.produceBarcodeHistoryAgainExport({
id: record.id
})
.then((res) => {
message.success('下载成功')
})
.catch(() => {
message.error('下载失败')
})
},
onCancel() {
console.log('Cancel')
}
})
}
const {
searchFormState,
tableRef,
selectedRowKeys,
columns,
loadData,
reset,
deleteBatchRecords,
options,
searchFormRef,
navigateTo,
deleteRecord
} = useTableManagement(
{
page: produceBarcodeHistoryApi.produceBarcodeHistoryPage
},
regionColumn,
['sysBrandEdit', 'sysBrandDelete']
)
</script>

View File

@ -0,0 +1,67 @@
export const personnelColumn = [
{
title: '编码',
dataIndex: 'number',
sorter: true,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '姓名',
dataIndex: 'name',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '可用状态',
dataIndex: 'enabledState',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '是否合适',
dataIndex: 'isFit',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '入群',
dataIndex: 'isJoinGroup',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '性别',
dataIndex: 'gender',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '分类',
dataIndex: 'categoryName',
align: 'center',
resizable: true,
width: 150
},
{
title: '电话号码',
dataIndex: 'phone',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
}
]

View File

@ -83,7 +83,7 @@
</template> </template>
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'number'"> <template v-if="column.dataIndex === 'number'">
<a href="#">{{ record.number }}</a> <span style="color: #1890ff;">{{ record.number }}</span>
</template> </template>
<template v-if="column.dataIndex === 'enabledState'"> <template v-if="column.dataIndex === 'enabledState'">
<a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag> <a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag>
@ -99,7 +99,6 @@
</template> </template>
<template v-if="column.dataIndex === 'action'"> <template v-if="column.dataIndex === 'action'">
<a-space> <a-space>
<a-tooltip title="查看">
<a <a
@click=" @click="
navigateTo('/employee/personnel/detail', { navigateTo('/employee/personnel/detail', {
@ -110,33 +109,48 @@
v-if="hasPerm('customerEdit')" v-if="hasPerm('customerEdit')"
> >
<EyeOutlined /> <EyeOutlined />
<!-- 查看--> 查看
</a> </a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" /> <a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-tooltip title="查看"> <a-dropdown>
<a <a class="ant-dropdown-link" @click.prevent>
更多
<DownOutlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item>
<a-button
type="link"
size="small"
@click=" @click="
navigateTo('/employee/personnel/detail', { navigateTo('/employee/personnel/detail', {
type: 'EDIT', type: 'EDIT',
id: record.id id: record.id
}) })
" "
v-if="hasPerm('customerEdit')" v-if="hasPerm('sysUnitEdit')"
> >
<FormOutlined /> <FormOutlined />
<!-- 编辑--> 编辑
</a>
</a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">
<DeleteOutlined />
<!-- 删除-->
</a-button> </a-button>
</a-popconfirm> </a-menu-item>
<a-menu-item>
<a-button
type="link"
danger
size="small"
v-if="hasPerm('materialDelete')"
@click="deleteRecord(record)"
>
<DeleteOutlined />
删除
</a-button>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space> </a-space>
</template> </template>
</template> </template>
@ -152,74 +166,7 @@
import employeeCategoryApi from '@/api/base/employee/employeeCategoryApi' import employeeCategoryApi from '@/api/base/employee/employeeCategoryApi'
import { useTableManagement } from '@/hook/useTableManagement' import { useTableManagement } from '@/hook/useTableManagement'
import PersonnelCategoryForm from '@/views/productionBusiness/employee/personnel/detail/personnelCategoryForm.vue' import PersonnelCategoryForm from '@/views/productionBusiness/employee/personnel/detail/personnelCategoryForm.vue'
import { personnelColumn } from '@/views/productionBusiness/employee/personnel/columns/materielColumn'
const materielColumn = [
{
title: '编码',
dataIndex: 'number',
sorter: true,
sortDirections: ['descend', 'ascend'],
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '姓名',
dataIndex: 'name',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '可用状态',
dataIndex: 'enabledState',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '是否合适',
dataIndex: 'isFit',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '入群',
dataIndex: 'isJoinGroup',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '性别',
dataIndex: 'gender',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
},
{
title: '分类',
dataIndex: 'categoryName',
align: 'center',
resizable: true,
width: 150
},
{
title: '电话号码',
dataIndex: 'phone',
align: 'center',
resizable: true,
width: 150,
ellipsis: true
}
]
const personnelCategoryFormRef = ref(null) const personnelCategoryFormRef = ref(null)
const dynamicTreeRef = ref(null) const dynamicTreeRef = ref(null)
@ -241,7 +188,7 @@
page: employeeApi.employeePage, page: employeeApi.employeePage,
delete: employeeApi.employeeDelete delete: employeeApi.employeeDelete
}, },
materielColumn, personnelColumn,
['customerEdit', 'customerDelete'] ['customerEdit', 'customerDelete']
) )

View File

@ -36,7 +36,7 @@
<a-card :bordered="false" class="mt-4"> <a-card :bordered="false" class="mt-4">
<a-tabs v-model:activeKey="activeKey"> <a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="人员信息"> <a-tab-pane key="1" tab="人员信息">
<a-table :dataSource="dataSource" :columns="columns" :pagination="false"> <a-table :dataSource="dataSource" :columns="columns" :pagination="false" bordered>
<template #bodyCell="{ column, record, index }"> <template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'index'"> <template v-if="column.dataIndex === 'index'">
{{ index + 1 }} {{ index + 1 }}

View File

@ -71,7 +71,7 @@
</template> </template>
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'number'"> <template v-if="column.dataIndex === 'number'">
<a href="#">{{ record.number }}</a> <span style="color: #1890ff">{{ record.number }}</span>
</template> </template>
<template v-if="column.dataIndex === 'enabledState'"> <template v-if="column.dataIndex === 'enabledState'">
<a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag> <a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag>
@ -90,38 +90,59 @@
v-if="hasPerm('customerEdit')" v-if="hasPerm('customerEdit')"
> >
<EyeOutlined /> <EyeOutlined />
<!-- 查看--> 查看
</a> </a>
</a-tooltip> </a-tooltip>
<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" /> <a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-tooltip title="编辑"> <a-dropdown>
<a <a class="ant-dropdown-link" @click.prevent>
更多
<DownOutlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item>
<a-button
type="link"
size="small"
@click=" @click="
navigateTo('/employee/personnelReport/detail', { navigateTo('/employee/personnelReport/detail', {
type: 'EDIT', type: 'EDIT',
id: record.id id: record.id
}) })
" "
v-if="hasPerm('customerEdit')" v-if="hasPerm('sysUnitEdit')"
> >
<FormOutlined /> <FormOutlined />
</a> 编辑
</a-tooltip>
<!-- <a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">
<DeleteOutlined />
&lt;!&ndash; 删除&ndash;&gt;
</a-button> </a-button>
</a-popconfirm>--> </a-menu-item>
<a-menu-item>
<a-divider type="vertical"></a-divider> <a-button
<a-tooltip title="添加标签"> type="link"
<a @click="handleOpenTag(record)" :style="{ color: record.tagColor }"> danger
size="small"
v-if="hasPerm('materialDelete')"
@click="deleteRecord(record)"
>
<DeleteOutlined />
删除
</a-button>
</a-menu-item>
<a-menu-item>
<a-button
type="link"
size="small"
@click="handleOpenTag(record)"
:style="{ color: record.tagColor }"
>
<TagFilled /> <TagFilled />
<!-- 查看--> 标签
</a> </a-button>
</a-tooltip> </a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space> </a-space>
</template> </template>
</template> </template>

View File

@ -1,29 +1,127 @@
<template> <template>
<div></div> <AdvancedSearchForm
:formState="searchFormState"
:formFields="searchFields"
@search="tableRef.refresh()"
@reset="tableRef.refresh()"
/>
<a-card :bordered="false" class="mt-4" style="height: 100%">
<a-row :gutter="24">
<a-col :span="6">
<dynamic-tree
ref="dynamicTreeRef"
treeTitle="物料分类"
:tableRef="tableRef"
:openFormRef="materialCategoryFormRef"
:apiModel="{
getTree: materialCategoryApi.materialCategoryTree,
delTree: materialCategoryApi.materialCategoryDelete
}"
@selectTree="selectTree"
@delTree="delTree"
@treeRefresh="treeRefresh"
:toolConfig="{
plus: false,
edit: false,
delete: false,
refresh: true
}"
></dynamic-tree>
</a-col>
<a-col :span="18">
<s-table
ref="tableRef"
:columns="columns"
:data="loadData"
:alert="options.alert.show"
bordered
:row-key="(record) => record.id"
:tool-config="options.toolConfig"
:scroll="{
x: 100
}"
>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'number'">
<span style="color: #0d84ff">{{ record.number }}</span>
</template>
<template v-if="column.dataIndex === 'enabledState'">
<a-tag color="#87d068" v-if="record.enabledState === 'ENABLE'"></a-tag>
<a-tag color="#f50" v-if="record.enabledState === 'DISABLED'"></a-tag>
</template>
<template v-if="column.dataIndex === 'type'">
{{ $TOOL.dictTypeData('OFFICIAL_ACCOUNT_TYPE', record.type) }}
</template>
<template v-if="column.dataIndex === 'action'">
<a-space>
<a> 打印标签 </a>
</a-space>
</template>
</template>
</s-table>
</a-col>
</a-row>
</a-card>
<material-category-form ref="materialCategoryFormRef" @successful="successful"></material-category-form>
</template> </template>
<script setup> <script setup name="materiel">
// const props = defineProps({}) import materialApi from '@/api/base/material/materialApi'
import materialCategoryApi from '@/api/base/material/materialCategoryApi'
// const emit = defineEmits() import MaterialCategoryForm from '@/views/productionBusiness/basicData/materiel/detail/materialCategoryForm.vue'
// import { useTableManagement } from '@/hook/useTableManagement'
onMounted(() => { import { materielColumn } from '@/views/productionBusiness/basicData/materiel/column/materiel-column'
console.log('Component mounted') import { searchFields } from '@/views/productionBusiness/basicData/materiel/formFields/searchFields'
// TODO: Add your onMounted code here
})
onUpdated(() => { const materialCategoryFormRef = ref(null)
console.log('Component updated') const dynamicTreeRef = ref(null)
// TODO: Add your onUpdated code here
})
onUnmounted(() => { const {
console.log('Component unmounted') searchFormState,
// TODO: Add your onUnmounted code here tableRef,
}) selectedRowKeys,
columns,
loadData,
deleteBatchRecords,
options,
navigateTo,
deleteRecord
} = useTableManagement(
{
page: materialApi.materialPage,
delete: materialApi.materialDelete
},
materielColumn,
['materialEdit', 'materialDelete']
)
// watch(() => {}, () => {}) const selectTree = (value) => {
searchFormState.value.categoryId = value.id
tableRef.value.refresh()
}
const treeRefresh = () => {
searchFormState.value.categoryId = null
tableRef.value.refresh()
}
const delTree = () => {
searchFormState.value.categoryId = null
tableRef.value.refresh()
}
const successful = () => {
searchFormState.value.categoryId = null
tableRef.value.refresh()
dynamicTreeRef.value.loadTreeData()
}
onMounted(() => {
dynamicTreeRef.value.loadTreeData()
})
</script> </script>
<style scoped></style>

View File

@ -0,0 +1,91 @@
<template>
<a-card title="产码中心">
<a-form :model="formData" ref="formRef">
<a-row :gutter="[20]">
<a-col :span="12">
<a-form-item label="码包配置" name="packageConfigId" :rules="[{ required: true, message: '请选择码包配置' }]">
<a-select
:options="codeOptions"
placeholder="请选择码包配置"
:field-names="{
value: 'id',
label: 'name'
}"
v-model:value="formData.packageConfigId"
></a-select>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="导出数量" name="count" :rules="[{ required: true, message: '请选择导出数量' }]">
<a-input-number
v-model:value="formData.count"
style="width: 100%"
placeholder="请输入导出数量"
></a-input-number>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="示例">
<a-input disabled style="width: 100%" placeholder="显示导出示例格式"></a-input>
</a-form-item>
</a-col>
</a-row>
</a-form>
<a-space>
<a-button @click="handleClick"></a-button>
<!-- <a-button>下载</a-button>-->
</a-space>
</a-card>
</template>
<script setup>
// const props = defineProps({})
// const emit = defineEmits()
//
import productCodePackageConfigApi from '@/api/production/productcode/productCodePackageConfigApi'
import productcodeApi from '@/api/production/productcode/productcodeApi'
import { message } from 'ant-design-vue'
import downloadUtil from '@/utils/downloadUtil'
let codeOptions = ref([])
const formData = ref({})
const formRef = ref(null)
onMounted(() => {
console.log('Component mounted')
// TODO: Add your onMounted code here
productCodePackageConfigApi.productCodePackageConfigList().then((res) => {
codeOptions.value = res
})
})
const handleClick = () => {
formRef.value
.validate()
.then(() => {
productcodeApi.productCodeSchemeProduce(formData.value).then((res) => {
downloadUtil.resultDownload(res)
// message.success('')
})
})
.catch((error) => {
console.log('error', error)
})
}
onUpdated(() => {
console.log('Component updated')
// TODO: Add your onUpdated code here
})
onUnmounted(() => {
console.log('Component unmounted')
// TODO: Add your onUnmounted code here
})
// watch(() => {}, () => {})
</script>
<style scoped></style>

View File

@ -1,4 +1,20 @@
export const reportColumns = [ export const reportColumns = [
{
title: '单号',
dataIndex: 'billNumber',
width: 200,
resizable: true,
align: 'center',
ellipsis: true
},
{
title: '源单号',
dataIndex: 'sourceBillNumber',
width: 200,
resizable: true,
align: 'center',
ellipsis: true
},
{ {
title: '业务日期', title: '业务日期',
dataIndex: 'businessDate', dataIndex: 'businessDate',
@ -9,14 +25,14 @@ export const reportColumns = [
sortDirections: ['descend', 'ascend'], sortDirections: ['descend', 'ascend'],
ellipsis: true ellipsis: true
}, },
{ /*{
title: '状态', title: '状态',
dataIndex: 'state', dataIndex: 'state',
width: 200, width: 200,
resizable: true, resizable: true,
align: 'center', align: 'center',
ellipsis: true ellipsis: true
}, },*/
{ {
title: '类型', title: '类型',
dataIndex: 'produceType', dataIndex: 'produceType',

View File

@ -57,7 +57,6 @@
</template> </template>
<template v-if="column.dataIndex === 'action'"> <template v-if="column.dataIndex === 'action'">
<a-space> <a-space>
<a-tooltip title="查看">
<a <a
@click=" @click="
navigateTo('/report/detail', { navigateTo('/report/detail', {
@ -68,8 +67,8 @@
v-if="hasPerm('customerEdit')" v-if="hasPerm('customerEdit')"
> >
<EyeOutlined /> <EyeOutlined />
查看
</a> </a>
</a-tooltip>
</a-space> </a-space>
</template> </template>
</template> </template>

View File

@ -78,7 +78,6 @@
</template> </template>
<template v-if="column.dataIndex === 'action'"> <template v-if="column.dataIndex === 'action'">
<a-space> <a-space>
<a-tooltip title="查看">
<a <a
@click=" @click="
navigateTo('/task/detail', { navigateTo('/task/detail', {
@ -89,39 +88,62 @@
v-if="hasPerm('customerEdit')" v-if="hasPerm('customerEdit')"
> >
<EyeOutlined /> <EyeOutlined />
<!-- 查看--> 查看
</a> </a>
</a-tooltip>
<a-divider <a-divider
type="vertical" type="vertical"
v-if="hasPerm(['customerEdit', 'customerDelete'], 'and') && record.state === '1'" v-if="hasPerm(['customerEdit', 'customerDelete'], 'and') && record.state === '1'"
/> />
<a-tooltip title="编辑"> <a-dropdown v-if="record.state === '1'">
<a <a class="ant-dropdown-link" @click.prevent>
更多
<DownOutlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item>
<a-button
type="link"
size="small"
@click=" @click="
navigateTo('/task/detail', { navigateTo('/task/detail', {
type: 'EDIT', type: 'EDIT',
id: record.id id: record.id
}) })
" "
v-if="hasPerm('customerEdit') && record.state === '1'" v-if="hasPerm('sysUnitEdit')"
> >
<FormOutlined /> <FormOutlined />
<!-- 编辑--> 编辑
</a>
</a-tooltip>
<a-divider
type="vertical"
v-if="hasPerm(['customerEdit', 'customerDelete'], 'and') && record.state === '1'"
/>
<a-popconfirm title="确定要删除吗?" @confirm="deleteRecord(record)">
<a-button type="link" danger size="small" v-if="hasPerm('customerDelete') && record.state === '1'">
<DeleteOutlined />
<!-- 删除-->
</a-button> </a-button>
</a-popconfirm> </a-menu-item>
<a-menu-item>
<a-button
type="link"
danger
size="small"
v-if="hasPerm('materialDelete')"
@click="deleteRecord(record)"
>
<DeleteOutlined />
删除
</a-button>
</a-menu-item>
<a-menu-item>
<a-button
type="link"
size="small"
@click="handleOpenTag(record)"
:style="{ color: record.tagColor }"
>
<TagFilled />
标签
</a-button>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space> </a-space>
</template> </template>
</template> </template>