feat:完成客户消息管理模块 fix:部分页面下拉框微调

This commit is contained in:
xjh 2023-08-01 15:10:39 +08:00
parent 164a017e67
commit 2aa65b54eb
6 changed files with 583 additions and 10 deletions

View File

@ -26,7 +26,7 @@
</el-col>
<el-col :span="12">
<el-form-item :label-width="labelWidth" label="全局模式" prop="code_module_category_global_mode">
<el-select style="width: 100%;" multiple v-model="formData.code_module_category_global_mode" clearable
<el-select filterable style="width: 100%;" multiple v-model="formData.code_module_category_global_mode" clearable
:disabled="commonFiledDisabled" placeholder="请选择">
<el-option v-for="item in global_mode" :key="item.dictionary_guid" :label="item.dictionary_name"
:value="item.dictionary_value"></el-option>
@ -35,8 +35,8 @@
</el-col>
<el-col :span="12">
<el-form-item :label-width="labelWidth" label="库类型" prop="code_module_category_library_type">
<el-select :disabled="commonFiledDisabled" v-model="formData.code_module_category_library_type" clearable
placeholder="请选择">
<el-select :disabled="commonFiledDisabled" filterable v-model="formData.code_module_category_library_type"
clearable placeholder="请选择">
<el-option v-for="item in library_type" :key="item.dicitonary_guid" :label="item.dictionary_name"
:value="parseInt(item.dictionary_value)"></el-option>
</el-select>
@ -44,8 +44,8 @@
</el-col>
<el-col :span="12">
<el-form-item :label-width="labelWidth" label="所属客户" prop="customer_guid">
<el-select :disabled="commonFiledDisabled" style="width: 100%;" v-model="formData.customer_guid" clearable
placeholder="请选择">
<el-select :disabled="commonFiledDisabled" filterable style="width: 100%;" v-model="formData.customer_guid"
clearable placeholder="请选择">
<el-option v-for="item in customerOptionList" :key="item.dictionary_guid" :label="item.customer_show_text"
:value="item.customer_guid"></el-option>
</el-select>

View File

@ -26,7 +26,7 @@
</el-col>
<el-col :span="12">
<el-form-item :label-width="labelWidth" label="全局模式" prop="code_module_category_global_mode">
<el-select :disabled="commonFiledDisabled" style="width: 100%;" multiple
<el-select filterable :disabled="commonFiledDisabled" style="width: 100%;" multiple
v-model="formData.code_module_category_global_mode" clearable placeholder="请选择">
<el-option v-for="item in global_mode" :key="item.dictionary_guid" :label="item.dictionary_name"
:value="item.dictionary_value"></el-option>
@ -35,8 +35,8 @@
</el-col>
<el-col :span="12">
<el-form-item :label-width="labelWidth" label="库类型" prop="code_module_category_library_type">
<el-select :disabled="commonFiledDisabled" v-model="formData.code_module_category_library_type" clearable
placeholder="请选择">
<el-select filterable :disabled="commonFiledDisabled" v-model="formData.code_module_category_library_type"
clearable placeholder="请选择">
<el-option v-for="item in library_type" :key="item.dictionary_guid" :label="item.dictionary_name"
:value="parseInt(item.dictionary_value)"></el-option>
</el-select>
@ -44,8 +44,8 @@
</el-col>
<el-col :span="12">
<el-form-item :label-width="labelWidth" label="所属客户" prop="customer_guid">
<el-select :disabled="commonFiledDisabled" style="width: 100%;" v-model="formData.customer_guid" clearable
placeholder="请选择">
<el-select filterable :disabled="commonFiledDisabled" style="width: 100%;" v-model="formData.customer_guid"
clearable placeholder="请选择">
<el-option v-for="item in customerOptionList" :key="item.dictionary_guid" :label="item.customer_show_text"
:value="item.customer_guid"></el-option>
</el-select>

View File

@ -0,0 +1,182 @@
<template>
<el-dialog v-model="dialogVisible" title="添加客户消息" width="900px" @closed="closeDialog" @open="openDialog">
<el-form ref="formRef" :model="formData" :rules="rules">
<el-row>
<el-col :span="12">
<el-form-item :label-width="labelWidth" label="标题" prop="customer_message_title">
<el-input v-model='formData.customer_message_title' type="text" placeholder='请输入标题'></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item :label-width="labelWidth" label="内容" prop="customer_message_content">
<el-input v-model='formData.customer_message_content' type="textarea" :rows="5"
placeholder='请输入消息内容'></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item :label-width="labelWidth" label="附言" prop="customer_message_postscript">
<el-input v-model='formData.customer_message_postscript' type="textarea" :rows="5"
placeholder='请输入附言'></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item :label-width="labelWidth" label="全部人" prop="customer_guid">
<el-switch v-model="formData.customer_all" class="ml-2"
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" />
</el-form-item>
</el-col>
</el-row>
<el-row v-if="!formData.customer_all">
<el-col :span="12">
<el-form-item :label-width="labelWidth" label="所属客户" prop="customer_guid">
<el-select filterable :disabled="commonFiledDisabled" style="width: 100%;" v-model="formData.customer_guid"
clearable placeholder="请选择">
<el-option v-for="item in customerOptionList" :key="item.dictionary_guid" :label="item.customer_show_text"
:value="item.customer_guid"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="handleAddClick(formRef)">添加</el-button>
<el-button @click="handleResetClick(formRef)">重置</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import { reactive, ref, watch } from "vue";
import { addCustomerMessage, getDictionary } from "~/service/customer_message";
import { getCustomerOptionList } from "~/service/customer";
import { useLoginStore } from "~/store";
// --
// --
//
const reading_status = ref([]);
async function get_reading_status() {
await getDictionary({ dictionary_value: 'reading_status' }).then((res) => {
reading_status.value = res
})
}
//
const customerOptionList = ref([]);
async function getCustomerOptions() {
await getCustomerOptionList().then((res) => {
customerOptionList.value = res.data
})
}
// --
const store = useLoginStore();
const headers = {
Accept: "application/json",
...store.headers,
};
const isBtnLod = ref(false);
const formRef = ref();
const labelWidth = 90;
const props = defineProps({
modelValue: Boolean,
done: Function,
});
const emits = defineEmits(["update:modelValue"]);
const dialogVisible = ref(props.modelValue);
const formData = reactive({
customer_all: false
});
const uoloadData = ref({
dirName: "CustomerMessage"
})
watch(props, (v) => {
dialogVisible.value = v.modelValue;
});
const rules = reactive({
customer_message_title: [
{
required: true,
message: '标题不能为空'
}
],
customer_message_content: [
{
required: true,
message: '内容不能为空'
}
],
customer_message_postscript: [
{
required: true,
message: '附言不能为空'
}
],
customer_message_reading_status: [
{
required: true,
message: '阅读状态不能为空'
}
],
});
// --
//
const openDialog = () => {
get_reading_status()
getCustomerOptions()
};
const closeDialog = () => {
handleResetClick(formRef.value);
dialogVisible.value = false;
emits("update:modelValue", false);
};
const handleAddClick = async (formEl) => {
if (!formEl) return;
formEl.validate(async (valid) => {
if (!valid) {
return;
}
isBtnLod.value = true;
const { code } = await addCustomerMessage(formData);
if (code == 0) {
closeDialog();
props.done();
}
isBtnLod.value = flase;
});
};
const handleResetClick = async (formEl) => {
if (!formEl) return;
formEl.resetFields();
};
</script>
<style lang="less" scoped></style>

View File

@ -0,0 +1,120 @@
<template>
<el-dialog v-model="props.modelValue" title="客户消息详情" width="900px" @closed="closeDialog" @open="openDialog">
<el-form ref="formRef" :model="formData" :disabled="true">
<el-row>
<el-col :span="12">
<el-form-item :label-width="labelWidth" label="标题" prop="customer_message_title">
<el-input v-model='formData.customer_message_title' type="text" placeholder='请输入标题'></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item :label-width="labelWidth" label="内容" prop="customer_message_content">
<el-input v-model='formData.customer_message_content' type="textarea" :rows="5"
placeholder='请输入消息内容'></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item :label-width="labelWidth" label="附言" prop="customer_message_postscript">
<el-input v-model='formData.customer_message_postscript' type="textarea" :rows="5"
placeholder='请输入附言'></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item :label-width="labelWidth" label="阅读状态" prop="customer_message_reading_status">
<el-select v-model="formData.customer_message_reading_status" clearable placeholder="请选择">
<el-option v-for="item in reading_status" :key="item.dictionary_guid" :label="item.dictionary_name"
:value="parseInt(item.dictionary_value)"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item :label-width="labelWidth" label="所属客户" prop="customer_guid">
<el-select filterable :disabled="commonFiledDisabled" style="width: 100%;" v-model="formData.customer_guid"
clearable placeholder="请选择">
<el-option v-for="item in customerOptionList" :key="item.dictionary_guid" :label="item.customer_show_text"
:value="item.customer_guid"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item :label-width="labelWidth" label="消息发送时间" prop="customer_message_title">
<el-input v-model='formData.customer_message_create_time' type="text" placeholder='请输入标题'></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-dialog>
</template>
<script setup>
import { reactive, ref, watch } from "vue";
import { isEmptyObject } from "~/utils/index";
import { getDictionary } from '~/service/customer_message';
import { getCustomerOptionList } from "~/service/customer";
// --
// --
//
const reading_status = ref([]);
async function get_reading_status() {
await getDictionary({ dictionary_value: 'reading_status' }).then((res) => {
reading_status.value = res
})
}
//
const customerOptionList = ref([]);
async function getCustomerOptions() {
await getCustomerOptionList().then((res) => {
customerOptionList.value = res.data
})
}
// --
const formRef = ref();
const labelWidth = 100;
const props = defineProps({
modelValue: Boolean,
data: Object,
done: Function,
});
const emits = defineEmits(["update:modelValue"]);
const formData = ref({
...props.data,
});
// --
watch(props, (v) => {
formData.value = v.data;
});
//
const openDialog = () => {
get_reading_status()
getCustomerOptions()
};
const closeDialog = () => {
emits("update:modelValue", false);
};
</script>
<style lang="less" scoped></style>

View File

@ -0,0 +1,212 @@
<template>
<!-- 面包屑 -->
<el-breadcrumb>
<el-breadcrumb-item>客户消息管理</el-breadcrumb-item>
<el-breadcrumb-item to="/customer_message/list">客户消息列表</el-breadcrumb-item>
</el-breadcrumb>
<!-- 搜索 -->
<el-form inline :model="params">
<el-form-item label="标题">
<el-input v-model='params.customer_message_title' placeholder='请输入标题'></el-input>
</el-form-item>
<el-form-item label="附言">
<el-input v-model='params.customer_message_postscript' placeholder='请输入附言'></el-input>
</el-form-item>
<el-form-item label="阅读状态">
<el-select v-model="params.customer_message_reading_status" clearable placeholder="请选择">
<el-option v-for="item in reading_status" :key="item.dictionary_guid" :label="item.dictionary_name"
:value="item.dictionary_value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="客户信息">
<el-input v-model='params.customer' placeholder='请输入客户名称/邮箱'></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="tableRef.reload()" icon="ElIconSearch">
搜索
</el-button>
</el-form-item>
</el-form>
<el-space style="margin-bottom: 10px;">
<!-- 添加客户消息 -->
<el-col :span="1">
<el-button type="primary" @click="addCustomerMessageDialogVisible = true"> 添加 </el-button>
</el-col>
<!-- 下拉操作 -->
<el-dropdown v-if="selectionData.length">
<el-button type="primary">
批量操作<el-icon class="el-icon--right"><arrow-down /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="handleDelete(selectionData)">
批量删除
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-space>
<!-- 数据表格 -->
<DataTable ref="tableRef" border style="width: 100%" :onSelectionChange="data => (selectionData = data)"
:column="column" :params="params" :request="params => getCustomerMessageList(params)">
<template #customer_message_reading_status='scope'>
<dict-tag :options='reading_status' :value='scope.row.customer_message_reading_status' />
</template>
<template #chaoz="scope">
<el-space>
<el-dropdown @command="handleCommand">
<el-button type="primary" size="small">
更多<el-icon class="el-icon--right"><arrow-down /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item :command="{ type: 'detail', row: scope.row }">
详情
</el-dropdown-item>
<el-dropdown-item :command="{ type: 'delete', row: scope.row }">
删除
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-space>
</template>
</DataTable>
<!-- 添加客户消息 -->
<AddCustomerMessageDialog v-model="addCustomerMessageDialogVisible" :done="() => tableRef.reload()">
</AddCustomerMessageDialog>
<!-- 客户消息详情 -->
<DetailCustomerMessageDialog v-model="DetailCustomerMessageDialogVisible" :data="DetailCustomerMessageDialogRow">
</DetailCustomerMessageDialog>
</template>
<script setup>
import { ArrowDown } from '@element-plus/icons-vue';
import { ref, reactive, watch } from 'vue';
import { useLoginStore } from "~/store";
import { getCustomerMessageList, editCustomerMessage, deleteCustomerMessage, getDictionary } from '~/service/customer_message';
import AddCustomerMessageDialog from './components/AddCustomerMessageDialog.vue';
import DetailCustomerMessageDialog from './components/DetailCustomerMessageDialog.vue';
const tableRef = ref();
const selectionData = ref([]);
const store = useLoginStore();
const addCustomerMessageDialogVisible = ref(false);
const DetailCustomerMessageDialogVisible = ref(false);
const DetailCustomerMessageDialogRow = ref({});
const headers = {
Accept: "application/json",
...store.headers,
};
//
const params = reactive({
customer_message_title: "",
customer_message_content: "",
customer_message_postscript: "",
customer_message_reading_status: "",
customer: "",
});
const column = [
{
fixed: true,
type: 'selection'
},
{
prop: "customer_message_title",
label: '标题',
width: '150'
},
{
prop: "customer_message_content",
label: '内容',
width: '150'
},
{
prop: "customer_message_postscript",
label: '附言',
width: '150'
},
{
prop: "customer_message_reading_status",
label: '阅读状态',
width: '90'
},
{
prop: "customer_name",
label: '客户名称',
width: '150'
},
{
prop: "customer_email",
label: '客户邮箱',
width: '180'
},
{
prop: "customer_message_create_time",
label: '发送时间',
width: '200'
},
{
label: '操作',
prop: 'chaoz',
width: '250',
fixed: 'right'
}
];
const handleCommand = ({ type, row }) => {
switch (type) {
case "detail":
handleDetail(row);
break;
case 'delete':
handleDelete([row]);
break;
}
};
//
const handleDelete = data => {
ElMessageBox.confirm(`您确定要删除该客户消息吗?`).then(async () => {
const res = await deleteCustomerMessage({
customer_message_guid: data.map(v => v.customer_message_guid).join()
});
if (res) {
tableRef.value.reload();
}
});
};
//
function handleUpdate(row) {
EditCustomerMessageDialogVisible.value = true
EditCustomerMessageDialogRow.value = row
}
//
function handleDetail(row) {
DetailCustomerMessageDialogVisible.value = true
DetailCustomerMessageDialogRow.value = row
}
//
const reading_status = ref([]);
async function get_reading_status() {
await getDictionary({ dictionary_value: 'reading_status' }).then((res) => {
reading_status.value = res
})
}
get_reading_status()
</script>

View File

@ -0,0 +1,59 @@
import { api, downloadFile, createApiUrl } from '~/utils/axios';
/**
* 获取字典值
* @param {Object} data
* @return {Promise} api
*/
export function getDictionary(data) {
return api.post('Dictionary.Dictionary/getDictionary', data, {
});
}
/**
* 获取客户消息列表
* @param {Object} data
* @return {Promise} api
*/
export function getCustomerMessageList(data) {
return api.post('Customer.CustomerMessage/getCustomerMessageList', data);
}
/**
* 删除客户消息
* @param {Object} data
* @return {Promise} api
*/
export function deleteCustomerMessage(data) {
return api.post('Customer.CustomerMessage/deleteCustomerMessage', data, {
isTransformResponse: true,
isShowSuccessMessage: true,
errorMessageText: '删除失败'
});
}
/**
* 添加客户消息
* @param {Object} data
* @return {Promise} api
*/
export function addCustomerMessage(data) {
return api.post('Customer.CustomerMessage/addCustomerMessage', data, {
isTransformResponse: true,
isShowSuccessMessage: true,
errorMessageText: '添加失败'
});
}
/**
* 编辑客户消息
* @param {Object} data
* @return {Promise} api
*/
export function editCustomerMessage(data) {
return api.post('Customer.CustomerMessage/editCustomerMessage', data, {
isTransformResponse: true,
isShowSuccessMessage: true,
errorMessageText: '编辑失败'
});
}