Commit e309e098 authored by tanjunxin's avatar tanjunxin

feat: 资料库模块开发完成提交

parent 6a0d260d
......@@ -72,13 +72,73 @@ export const getUserList = (params: any) => {
/**
* 获取客户资料列表
* 获取资料库类型列表
* @param params
* @returns
*/
export const getInformationList = (params: any) => {
export const getInformationTypeListApi = (params: any) => {
return axios.get('/api/information/typePage', {
params,
headers: formHeader
})
}
/**
* 获取资料库title
* @param params
* @returns
*/
export const getInformationListTitlesApi = (params: any) => {
return axios.get('/api/information/listInformationTitles', {
params,
headers: formHeader
})
}
/**
* 获取资料库列表数据
* @param params
* @returns
*/
export const getInformationListApi = (data: any) => {
return axios.post('/api/information/listInformation', data)
}
/**
* 导入客户资料
* @param params
* @returns
*/
export const importInformationApi = (data: any) => {
return axios.post('/api/information/loadInformation', data)
}
/**
* 新增资料库列表数据
* @param params
* @returns
*/
export const addInformationInfoApi = (data: any) => {
return axios.post('/api/information/add', data)
}
/**
* 修改资料库列表数据
* @param params
* @returns
*/
export const updateInformationInfoApi = (data: any) => {
return axios.post('/api/information/updateByID', data)
}
/**
* 删除资料库列表数据
* @param params
* @returns
*/
export const delInformationInfoApi = (params: any) => {
return axios.get('/api/information/deleteByID', {
params,
headers: formHeader
})
}
\ No newline at end of file
<template>
<div class="h-full flex flex-col bg-white p-2">
<p class="font-bold text-lg leading-10 border-b-2">资料库</p>
<el-form class="pt-2" :model="formState" inline>
<el-form-item label="资料名称">
<el-input v-model="formState.customerName"></el-input>
<div class="h-full flex flex-col bg-white p-2">
<p class="font-bold text-lg leading-10 border-b-2">资料库</p>
<el-form class="pt-2" ref="formRef" :model="form" inline>
<el-form-item label="资料名称" prop="type">
<el-input v-model="form.type"></el-input>
</el-form-item>
<el-form-item>
<el-button @click="">重置</el-button>
<el-button @click="" type="primary">查询</el-button>
<el-button @click="onReset">重置</el-button>
<el-button @click="onSearch" type="primary">查询</el-button>
</el-form-item>
</el-form>
<el-space wrap>
<el-card v-for="informationType in informationTypes" :key="informationType" class="box-card" @click="handleInfoTypeClick(informationType)">
<div class="text item">
{{ informationType }}
</div>
</el-card>
</el-space>
<el-row style="margin-bottom: 18px">
<el-col :span="24">
<el-button type="primary" @click="handleImport">导入</el-button>
</el-col>
</el-row>
<el-space wrap>
<el-card v-for="informationType in informationTypes" :key="informationType" class="box-card"
@click="handleInfoTypeClick(informationType)">
<div class="text item">
{{ informationType }}
</div>
</el-card>
</el-space>
<UploadInformationInfoDialog :visible="importVisible" @onImportChange="onImportChange" />
</div>
</template>
<script lang="ts" setup>
import { defineComponent, ref, onMounted, reactive, watch, unref } from 'vue'
import { getInformationList } from '@/api/customer'
import type { VxeTableInstance } from 'vxe-table'
import { useRouter } from 'vue-router'
const loading = ref(false)
const router = useRouter()
const xTable = ref<VxeTableInstance>()
const tableData = ref([])
const informationTypes = ref([])
const queryParam = reactive({
type:""
})
const formState = reactive({
customerName: '',
customerNickName: '',
currentPage: 1,
pageSize: 10,
total: 0
})
const mode = ref('')
const fileUpload = (info: any) => {
mode.value = 'edit'
}
<script lang="ts" setup>
import { ref, onMounted, reactive, unref } from 'vue'
import { getInformationTypeListApi } from '@/api/customer'
import { useRouter } from 'vue-router'
import { ElMessage, type FormInstance } from 'element-plus'
import UploadInformationInfoDialog from './components/upload-information-info-dialog.vue';
const loading = ref(false)
const router = useRouter()
const informationTypes = ref([])
const formRef = ref<FormInstance>()
const form = reactive({
type: '',
currentPage: 1,
pageSize: 10,
})
const importVisible = ref(false)
const queryCustomer = async () => {
loading.value = true
try {
// 模糊查询
const { data } = await getInformationList(unref(formState))
informationTypes.value = data.result
console.log(informationTypes)
formState.total = +data.result.total
} catch {}
const queryCustomer = async () => {
loading.value = true
try {
const { data } = await getInformationTypeListApi(unref(form))
informationTypes.value = data.result
} catch (error) {
} finally {
loading.value = false
}
}
const onReset = () => {
if (formRef?.value) {
formRef?.value.resetFields()
}
onSearch()
}
const handleInfoTypeClick = (informationType: any) => {
alert(informationType)
const onSearch = () => {
queryCustomer()
}
const handleImport = () => {
importVisible.value = true
}
const onImportChange = (type: any) => {
importVisible.value = false
if (type != 'close') {
onReset()
}
onMounted(() => {
queryCustomer()
}
const handleInfoTypeClick = (informationType: any) => {
router.push({
path: "/customer-excel-list",
query: {
informationType: informationType
}
})
</script>
}
onMounted(() => {
queryCustomer()
})
</script>
<style lang="scss" scoped>
:deep(.el-card) {
cursor: pointer;
}
</style>
\ No newline at end of file
<template>
<div class="h-full flex flex-col bg-white p-2">
<p class="font-bold text-lg leading-10 border-b-2">客户资料</p>
<el-form class="pt-2" :model="formState" inline>
<el-form-item label="资料名称">
<el-input v-model="formState.customerName"></el-input>
</el-form-item>
<el-form-item>
<el-button @click="">重置</el-button>
<el-button @click="" type="primary">查询</el-button>
</el-form-item>
</el-form>
<el-space wrap>
<el-card v-for="informationType in informationTypes" :key="informationType" class="box-card" @click="handleInfoTypeClick(informationType)">
<div class="text item">
{{ informationType }}
</div>
</el-card>
</el-space>
</div>
</template>
<script lang="ts" setup>
import { defineComponent, ref, onMounted, reactive, watch, unref } from 'vue'
import { getInformationList } from '@/api/customer'
import type { VxeTableInstance } from 'vxe-table'
import { useRouter } from 'vue-router'
const loading = ref(false)
const router = useRouter()
const xTable = ref<VxeTableInstance>()
const tableData = ref([])
const informationTypes = ref([])
const queryParam = reactive({
type:""
<div class="w-full h-full bg-white p-4">
<p class="font-bold text-lg leading-10 border-b-2">资料库管理</p>
<el-form class="pt-4" ref="formRef" :model="form" inline>
<el-form-item v-for="(item, index) in formColumn" :label="item" :key="index" :prop="item">
<el-input v-model="form[item]" placeholder="" clearable />
</el-form-item>
<el-form-item>
<el-button type="default" @click="onReset">重置</el-button>
<el-button type="primary" @click="onSearch">查询</el-button>
<el-button type="primary" @click="onCopy">查询参数</el-button>
</el-form-item>
</el-form>
<div>
<vxe-toolbar>
<template #buttons>
<el-button type="primary" @click="handleAdd">新增</el-button>
<el-button type="primary" @click="handleImport">导入</el-button>
<!-- <el-button type="danger" @click="handleDel">删除</el-button> -->
</template>
</vxe-toolbar>
<vxe-table ref="xTable" size="small" min-height="460" border :loading="loading" :data="tableData">
<vxe-column v-for="(row, index) in tableColumn" :field="row" :title="row" :key="index" />
<vxe-column title="操作" width="100" fixed="right">
<template #default="{ row }">
<el-button link type="primary" size="small" @click="handleUpdate(row)">修改</el-button>
<el-button link type="danger" size="small" @click="handleDel(row)">删除</el-button>
</template>
</vxe-column>
</vxe-table>
<vxe-pager v-if="total > 0" size="small" background v-model:current-page="form.currentPage"
v-model:page-size="form.pageSize" :total="total" @page-change="onSearch"
:layouts="['PrevPage', 'JumpNumber', 'NextPage', 'Sizes', 'FullJump', 'Total']">
</vxe-pager>
</div>
<InformationInfoDialog :visible="visible" :title="title" :informationInfo="informationInfo" @onChange="onChange" />
<UploadInformationInfoDialog :visible="importVisible" @onImportChange="onImportChange" />
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue'
import { getInformationListTitlesApi, getInformationListApi, delInformationInfoApi } from '@/api/customer'
import { ElMessage, ElMessageBox, type FormInstance, type Action } from 'element-plus'
import type { VxeTableInstance } from 'vxe-table'
import { useRoute } from 'vue-router'
import InformationInfoDialog from './components/information-info-dialog.vue';
import UploadInformationInfoDialog from './components/upload-information-info-dialog.vue';
const route = useRoute()
const loading = ref(false)
const formRef = ref<FormInstance>()
const formColumn = ref([])
const form = ref<any>({})
const total = ref(0)
const xTable = ref<VxeTableInstance>()
const tableData = ref([])
const tableColumn = ref([])
const visible = ref(false)
const informationInfo = ref({})
const title = ref("新增资料")
const importVisible = ref(false)
const initData = async () => {
loading.value = true
try {
const params = {
informationType: route.query.informationType
}
const { data } = await getInformationListTitlesApi(params)
if (data?.code == 200) {
tableColumn.value = data?.result.filter((item: any) => {
if (!['id', '_X_ROW_KEY'].includes(item)) {
return item
}
})
const formState = reactive({
customerName: '',
customerNickName: '',
currentPage: 1,
pageSize: 10,
total: 0
formColumn.value = data?.result.filter((item: any) => {
if (!['id', '_X_ROW_KEY'].includes(item)) {
return item
}
})
const queryInfomartionList = async () => {
loading.value = true
try {
// 模糊查询
const { data } = await getInformationList(unref(formState))
informationTypes.value = data.result
console.log(informationTypes)
formState.total = +data.result.total
} catch {}
loading.value = false
}
const handleInfoTypeClick = (informationType: any) => {
alert(informationType)
}
onMounted(() => {
queryInfomartionList()
formColumn.value.forEach((ele: any) => {
form.value[ele] = ""
});
getInformationListApi(params).then((res) => {
if (res.data?.code == 200) {
tableData.value = res.data?.result
}
})
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
}
} catch (error) {
} finally {
loading.value = false
}
}
const getInformationList = async (params: any) => {
loading.value = true
try {
const res = await getInformationListApi(params);
if (res.data?.code == 200) {
tableData.value = res.data?.result
}
} catch (error) {
} finally {
loading.value = false
}
}
const onReset = () => {
if(formRef?.value) {
formRef?.value.resetFields()
}
const params = {
informationType: route.query.informationType
}
getInformationList(params)
}
const onSearch = () => {
const params = {
informationType: route.query.informationType,
json: JSON.stringify(form.value)
}
getInformationList(params)
}
const onCopy = () => {
const data = Object.keys(form.value).reduce((acc: any, key) => {
if (form.value[key]) {
acc[key] = form.value[key]
}
return acc
}, {})
ElMessageBox.confirm(data, '查询参数', {
confirmButtonText: '复制',
cancelButtonText: '取消'
}).then(() => {
const input = document.createElement("input")
input.value = JSON.stringify(data)
document.body.appendChild(input)
input.select()
document.execCommand("Copy")
document.body.removeChild(input)
ElMessage({
type: 'success',
message: '复制成功'
})
})
}
const onChange = (type: any) => {
visible.value = false
if (type != 'close') {
onReset()
}
}
const handleAdd = () => {
visible.value = true
title.value = "新增资料"
informationInfo.value = form.value
}
const handleUpdate = (row: any) => {
visible.value = true
title.value = "修改资料"
informationInfo.value = Object.assign(form.value, row)
}
const handleDel = async (row: any) => {
const params = {
informationType: route.query.informationType,
id: row.id
}
const { data } = await delInformationInfoApi(params)
if (data?.code == 200) {
ElMessage.success(`${data?.message}`)
onReset()
} else {
ElMessage.error(`${data?.message}`)
}
}
const handleImport = () => {
importVisible.value = true
}
const onImportChange = (type: any) => {
importVisible.value = false
if (type != 'close') {
initData()
}
}
onMounted(() => {
if (!route.query.informationType) {
return
}
initData()
})
</script>
<style lang="scss" scoped></style>
<template>
<vxe-modal v-model="show" :z-index="1006" @hide="onClose" :title="title" width="600" esc-closable mask-closable
show-footer>
<template #default>
<el-form ref="formRef" :model="form" inline label-position="right">
<template v-for="(item, index) in formColumn" :key="index">
<el-form-item v-if="!['id', '_X_ROW_KEY'].includes(item)" :label="item" :prop="item">
<el-input v-model="form[item]" placeholder="" clearable />
</el-form-item>
</template>
</el-form>
</template>
<template #footer>
<el-button type="primary" @click="onSubmit">确认</el-button>
</template>
</vxe-modal>
</template>
<script lang="ts" setup name="InformationInfoDialog">
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { addInformationInfoApi, updateInformationInfoApi } from '@/api/customer'
import { ElMessage, type FormInstance } from 'element-plus'
const route = useRoute()
const props = defineProps({
visible: {
type: Boolean,
default: false
},
title: {
type: String,
default: "新增资料"
},
informationInfo: {
type: Object,
default: () => { }
}
})
const emits = defineEmits(['onChange'])
const show = ref(false)
const formRef = ref<FormInstance>()
const formColumn = ref<any>([])
const form = ref<any>({})
watch(
() => props.visible,
(val) => {
show.value = val
formColumn.value = Object.keys(props.informationInfo)
form.value = props.informationInfo
}
)
const addInformationInfo = async () => {
const params = {
informationType: route.query.informationType,
json: JSON.stringify(form.value)
}
const { data } = await addInformationInfoApi(params)
if (data?.code == 200) {
ElMessage.success(`${data?.message}`)
emits('onChange', 'add')
} else {
ElMessage.error(`${data?.message}`)
}
}
const updateInformationInfo = async () => {
delete form.value['_X_ROW_KEY']
const params = {
informationType: route.query.informationType,
json: JSON.stringify(form.value)
}
const { data } = await updateInformationInfoApi(params)
if (data?.code == 200) {
ElMessage.success(`${data?.message}`)
emits('onChange', 'update')
} else {
ElMessage.error(`${data?.message}`)
}
}
const onSubmit = () => {
if (props.title == '新增资料') {
addInformationInfo()
} else {
updateInformationInfo()
}
}
const onClose = () => {
emits('onChange', 'close')
}
</script>
<style lang="scss" scoped></style>
\ No newline at end of file
<template>
<vxe-modal v-model="show" :z-index="1006" @hide="onClose" title="导入" width="600" esc-closable mask-closable
show-footer>
<template #default>
<el-form ref="formRef" :model="form" :rules="rules">
<el-form-item label="资料类型" prop="informationType">
<el-input v-model="form.informationType" :disabled="!!route.query.informationType" clearable />
</el-form-item>
<el-form-item label="文件" prop="filePath">
<el-upload action="" ref="uploadRef" accept=".xlsx,.xls" :on-remove="handleRemove" :auto-upload="false"
:on-exceed="handleExceed" :limit="1" :on-change="handleUpload">
<el-button type="primary">上传文件</el-button>
<template #tip>
<div class="el-upload__tip">选择你要上传的excel文件,仅支持xlsx、xls格式</div>
</template>
</el-upload>
</el-form-item>
</el-form>
<el-card>
<template #header>
<div class="card-header">
<span>默认字段</span>
</div>
</template>
<el-button type="primary" style="margin-bottom: 12px;" @click="handleAdd">新增</el-button>
<el-table :data="tableData" border max-height="250" style="width: 100%">
<el-table-column prop="key" label="字段名称" align="center">
<template #default="scope">
<el-input v-model="scope.row.key" />
</template>
</el-table-column>
<el-table-column prop="value" label="字段值" align="center">
<template #default="scope">
<el-input v-model="scope.row.value" />
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="100">
<template #default="scope">
<el-button link type="primary" @click="handleDelete(scope.row, scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</template>
<template #footer>
<el-button @click="onClose">取消</el-button>
<el-button type="primary" @click="onSubmit">确认</el-button>
</template>
</vxe-modal>
</template>
<script lang="ts" setup name="UploadInformationInfoDialog">
import { ref, reactive, watch } from 'vue'
import { useRoute } from 'vue-router'
import { uploadFile } from '@/api/excel'
import { importInformationApi } from '@/api/customer'
import { ElMessage, genFileId, type FormInstance, type UploadInstance } from 'element-plus'
const route = useRoute()
const props = defineProps({
visible: {
type: Boolean,
default: false
}
})
const emits = defineEmits(['onImportChange'])
const show = ref(false)
const formRef = ref<FormInstance>()
const form = reactive<any>({
informationType: "",
filePath: "",
defaultJson: ""
})
const rules = reactive({
informationType: { required: true, message: '请输入资料类型', trigger: 'change' },
filePath: { required: true, message: '请选择要导入的文件', trigger: 'change' }
})
const uploadRef = ref<UploadInstance>()
const tableData = ref<any>([])
watch(
() => props.visible,
(val) => {
show.value = val
onReset()
if (route.query.informationType) {
form.informationType = route.query.informationType;
}
}
)
const importInformation = async () => {
const temp = tableData.value.reduce((acc: any, cur: any) => {
acc[cur.key] = cur.value || ''
return acc
}, {})
const params = {
informationType: form.informationType,
filePath: form.filePath,
defaultJson: temp
}
const { data } = await importInformationApi(params)
if (data?.code == 200) {
ElMessage.success(`${data?.message}`)
emits('onImportChange', 'submit')
} else {
ElMessage.error(`${data?.message}`)
}
}
const handleRemove = () => {
form.filePath = ''
}
const handleExceed = (files: any) => {
uploadRef.value!.clearFiles()
const file = files[0]
file.uid = genFileId()
uploadRef.value!.handleStart(file)
}
const handleUpload = (file: any) => {
const formData = new FormData()
formData.append('file', file.raw)
uploadFile(formData).then(({ data }) => {
if (data?.code === 200) {
form.filePath = data.message
} else {
return ElMessage.error('上传失败!')
}
})
}
const handleAdd = () => {
tableData.value.push({})
}
const handleDelete = (row: any, index: any) => {
tableData.value.splice(index, 1)
}
const onReset = () => {
if (formRef?.value) {
formRef?.value.resetFields()
}
tableData.value = []
}
const onSubmit = () => {
importInformation()
}
const onClose = () => {
emits('onImportChange', 'close')
}
</script>
<style lang="scss" scoped></style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment