tobacco/bs-ui/src/views/broker/product/components/BrokerProduct.vue

834 lines
28 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div ref="list">
<el-form :model="queryParams" ref="queryForm" size="mini" :inline="true" v-show="showSearch" label-width="100px">
<el-form-item label="产品名称" prop="productName">
<el-input
v-model="queryParams.productName"
placeholder="请输入产品名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="产品类型" prop="productType">
<el-select v-model="queryParams.productType" placeholder="选择产品类型" clearable @keyup.enter.native="handleQuery">
<el-option v-for="dict in dict.type.product_type" :key="dict.value" :label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="选择状态" clearable @keyup.enter.native="handleQuery">
<el-option v-for="dict in dict.type.product_status" :key="dict.value" :label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
<!-- <el-form-item label="上架时间" prop="listBegin">-->
<!-- <el-date-picker clearable-->
<!-- style="width: 170px"-->
<!-- v-model="queryParams.listBegin"-->
<!-- type="date"-->
<!-- value-format="yyyy-MM-dd"-->
<!-- placeholder="请选择上架时间起">-->
<!-- </el-date-picker>-->
<!-- - -->
<!-- <el-date-picker clearable-->
<!-- style="width: 170px"-->
<!-- v-model="queryParams.listEnd"-->
<!-- type="date"-->
<!-- value-format="yyyy-MM-dd"-->
<!-- placeholder="请选择上架时间止">-->
<!-- </el-date-picker>-->
<!-- </el-form-item>-->
<el-form-item label="上架时间">
<el-date-picker
v-model="dateRange"
style="width: 200px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
:disabled="!brokerId"
v-hasPermi="['product:info:add']"
>选择
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['product:info:edit']"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['product:info:remove']"
>移除
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['product:info:export']"
>导出
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="infoList" @sort-change="handleSortChange" :height="tableHeight - 150"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="所属代理商" prop="brokerName" fixed="left" width="100"/>
<el-table-column label="产品名称" prop="productName" sortable='custom' fixed="left" width="100"/>
<el-table-column label="产品简称" prop="simpleName" sortable='custom' width="100"/>
<el-table-column label="产品类型" prop="productType" sortable='custom' width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.product_type" :value="scope.row.productType"/>
</template>
</el-table-column>
<!-- <el-table-column label="产品细类" align="center" prop="productSubtype" sortable='custom' width="100"/> -->
<el-table-column label="最高额度(元)" prop="maxAmount" sortable='custom' width="120"/>
<el-table-column label="年利率(单利)" prop="interestRate" sortable='custom' width="120"/>
<!-- <el-table-column label="产品简介" align="center" prop="productIntro" sortable='custom' show-overflow-tooltip
width="100"/> -->
<!-- <el-table-column label="产品详情" align="center" prop="productDetail" sortable='custom' show-overflow-tooltip
width="100"/> -->
<el-table-column label="还款周期" prop="repaymentCycle" sortable='custom' width="100"/>
<el-table-column label="还款方式" prop="repaymentMethod" sortable='custom' width="100"/>
<el-table-column label="展业城市" prop="businessCity" sortable='custom' width="100"
show-overflow-tooltip/>
<el-table-column label="综合费率" prop="combinedRates" sortable='custom' width="100"/>
<el-table-column label="上架时间起" prop="listBegin" width="150" sortable='custom'>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.listBegin, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="上架时间止" prop="listEnd" width="150" sortable='custom'>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.listEnd, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status" sortable='custom'>
<template slot-scope="scope">
<dict-tag :options="dict.type.product_status" :value="scope.row.status"/>
</template>
</el-table-column>
<!-- <el-table-column label="备注" align="center" prop="remark" sortable='custom' show-overflow-tooltip/> -->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120" fixed="right">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['product:info:edit']"
>修改
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['product:info:remove']"
>移除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改代理商经纪对话框 -->
<el-dialog :title="title" :visible.sync="open" width="70%" append-to-body :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="115px">
<el-row>
<el-col :span="8">
<el-form-item label="所属代理商" prop="brokerId">
<treeselect v-model="form.brokerId" :options="brokerList" props="lable" :show-count="true"
:defaultExpandLevel="Infinity" disabled
placeholder="请选择归属部门" :normalizer="tenantIdnormalizer"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="产品名称" prop="id">
<el-select style="width: 100%;" filterable v-model="form.id" placeholder="请选择产品名称" @change="handleChange"
clearable>
<el-option v-for="info in infoListAll" :key="info.id" :label="info.productName"
:value="info.id"/>
</el-select>
<!-- <el-input v-model="form.productName" placeholder="请输入产品名称"/>-->
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="产品简称" prop="simpleName">
<el-input v-model="form.simpleName" placeholder="请输入产品简称" disabled/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="产品类型" prop="productType">
<el-select style="width: 100%;" v-model="form.productType" placeholder="选择产品类型" clearable disabled>
<el-option v-for="dict in dict.type.product_type" :key="dict.value" :label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="产品细类" prop="productSubtype">
<el-input v-model="form.productSubtype" placeholder="请输入产品细类" disabled/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="最高额度(元)" prop="maxAmount">
<el-input-number v-model="form.maxAmount" placeholder="请输入最高额度(元)" style="width: 100%;" :min="0"
disabled/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="还款周期" prop="repaymentCycle">
<el-input v-model="form.repaymentCycle" placeholder="请输入还款周期" disabled/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="还款方式" prop="repaymentMethod">
<el-input v-model="form.repaymentMethod" placeholder="请输入还款方式" disabled/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="综合费率" prop="combinedRates">
<el-input v-model="form.combinedRates" placeholder="请输入综合费率" disabled/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="上架时间起" prop="listBegin">
<el-date-picker clearable
disabled
v-model="form.listBegin"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择上架时间起"
style="width: 100%;">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="上架时间止" prop="listEnd">
<el-date-picker clearable
disabled
v-model="form.listEnd"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择上架时间止"
style="width: 100%;">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="状态" prop="status">
<el-select style="width: 100%;" v-model="form.status" placeholder="选择状态" clearable disabled>
<el-option v-for="dict in dict.type.product_status" :key="dict.value" :label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="展业城市" prop="businessCityByName">
<el-input v-model="form.businessCityByName" placeholder="选择展业城市" style="width: 100%;" readonly>
<el-button slot="append" icon="el-icon-arrow-down" @click="openModal"></el-button>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="年利率(单利%)" prop="interestRateBegin">
<el-input-number v-model="form.interestRateBegin" style="width: 150px;" :min="0" :precision="2" disabled/>
-
<el-input-number v-model="form.interestRateEnd" style="width: 150px;" :min="0" :precision="2" disabled/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="产品简介" prop="productIntro">
<editor v-model="form.productIntro" :min-height="92" disabled/>
<!-- <el-input v-model="form.productIntro" type="textarea" placeholder="请输入内容"/>-->
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="产品详情" prop="productDetail">
<editor v-model="form.productDetail" :min-height="152" disabled/>
<!-- <el-input v-model="form.productDetail" type="textarea" placeholder="请输入内容"/>-->
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" disabled/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
<el-dialog :visible.sync="showModal" title="选择城市" @close="closeModal">
<el-row>
<el-col :span="12">
<h3 class="section-title">城市列表</h3>
<el-input v-model="searchText" placeholder="请输入城市名称" clearable></el-input>
<div class="city-tree-container">
<el-tree
:data="filteredCities"
:props="defaultProps"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="tree"
node-key="id"
:default-expand-all="false"
highlight-current
>
<template v-slot="{ node, data }">
<div class="city-item">
<span>{{ node.label }}</span>
<!-- <el-button @click="selectCity(data)" type="text" size="mini" class="add-button">添加</el-button>-->
</div>
</template>
</el-tree>
</div>
</el-col>
<el-col :span="12">
<h3 class="section-title">已选择城市</h3>
<ul class="selected-city-list">
<li v-for="(city, index) in selectedCities" :key="index">
<div class="selected-city-item">
{{ city.name }}
<!-- <el-button @click="removeCity(index)" type="text" size="mini">移除</el-button>-->
</div>
</li>
</ul>
</el-col>
</el-row>
<div slot="footer">
<el-button @click="confirmSelection"></el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import AutoTableHeight from '@/views/broker/AutoTableHeight';
import {
pageListInfo,
getInfo,
delInfo,
addInfo,
updateInfo,
listInfo,
editByBroker,
delInfoByBroker,
listByBroker,
getInfoByBroker,
} from "@/api/product/info";
import {listArea} from "@/api/system/area";
import {listBrokerByTree} from "@/api/broker/broker";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
name: "BrokerUser",
mixins: [AutoTableHeight],
dicts: ['product_type', "product_status"],
components: {Treeselect},
props: {
rowData: {
type: Object,
default: () => ({})
}
},
data() {
return {
// isReadOnly: false,
brokerList: [],
infoListAll: [],
brokerId: null,
// 日期范围
dateRange: [],
rowDataNew: {},
defaultProps: {
children: "children",
label: "name"
},
searchText: '',
showModal: false,
selectedCities: [],
cityList: [],
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 选中名字
names: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 产品信息表格数据
infoList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
productName: null,
simpleName: null,
productType: null,
productSubtype: null,
maxAmount: null,
interestRate: null,
productIntro: null,
productDetail: null,
listBegin: null,
listEnd: null,
status: null,
maxAmountBegin: undefined,
maxAmountEnd: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
id: [
{required: true, message: "产品名称不能为空", trigger: "blur"}
],
simpleName: [
{required: true, message: "产品简称不能为空", trigger: "blur"}
],
productType: [
{required: true, message: "产品类型不能为空", trigger: "change"}
],
// productSubtype: [
// {required: true, message: "产品细类不能为空", trigger: "change"}
// ],
maxAmount: [
{required: true, message: "最高额度(元)不能为空", trigger: "blur"}
],
interestRateBegin: [
{required: true, message: "年利率(单利)不能为空", trigger: "blur"}
],
// productIntro: [
// {required: true, message: "产品简介不能为空", trigger: "blur"}
// ],
// productDetail: [
// {required: true, message: "产品详情不能为空", trigger: "blur"}
// ],
// listBegin: [
// {required: true, message: "上架时间起不能为空", trigger: "blur"}
// ],
// listEnd: [
// {required: true, message: "上架时间止不能为空", trigger: "blur"}
// ],
status: [
{required: true, message: "状态不能为空", trigger: "change"}
],
// remark: [
// {required: true, message: "备注不能为空", trigger: "blur"}
// ],
}
};
},
mounted() {
// 初始化时将 rowData 的值赋给 row
this.rowDataNew = this.rowData;
},
watch: {
// 监听 rowData 的变化
rowData: function (newVal, oldVal) {
// 当 rowData 变化时更新 row 的值并打印
this.rowDataNew = newVal;
this.brokerId = this.rowDataNew.id;
// const allIds = this.getAllIds(this.rowDataNew);
this.queryParams.brokerIds = this.brokerId;
this.getList();
},
},
computed: {
filteredCities() {
// 根据搜索文本过滤城市列表
return this.cityList.filter(city => city.name.includes(this.searchText));
}
},
created() {
this.getList();
this.getAreaList();
},
methods: {
tenantIdnormalizer(node, instanceId) {
if (node.children && !node.children.length) {
delete node.children
}
return {
id: node.id,
label: node.brokerName,
children: node.children
}
},
getbrokerList() {
listBrokerByTree().then(response => {
this.brokerList = response.data;
});
},
handleChange() {
getInfo(this.form.id).then(response => {
var brokerId = this.form.brokerId;
this.form = response.data;
this.form.brokerId = brokerId;
this.getAllInfo();
this.getList();
});
},
getAllInfo(id) {
var params = {
selectByBroker: "1",
brokerId: this.rowData.id,
id: id
}
listByBroker(params).then(response => {
this.infoListAll = response.data;
});
},
getAllIds(data) {
let ids = [];
ids.push(data.id);
if (data.children && Array.isArray(data.children)) {
// 遍历 children 数组
data.children.forEach(child => {
// 递归调用 getAllIds 函数,获取当前子对象及其子对象的 id并添加到 ids 数组中
ids = ids.concat(this.getAllIds(child));
});
}
return ids.join(',');
},
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
openModal() {
this.showModal = true;
let selectedCities = [];
let businessCities = this.form.businessCity.split(',');
businessCities.forEach(cityId => {
let matchedCity = this.cityList.find(city => city.areaId == cityId);
if (matchedCity) {
selectedCities.push({
areaId: matchedCity.areaId,
name: matchedCity.name
});
}
});
this.selectedCities = selectedCities;
},
closeModal() {
// 关闭模态窗口
this.showModal = false;
this.searchText = '';
this.selectedCities = [];
},
selectCity(city) {
// 检查城市是否已经添加
if (this.isCitySelected(city)) {
this.$message.warning('该城市已经添加过了!');
} else {
this.selectedCities.push(city);
this.$message.success('成功添加城市!');
}
},
isCitySelected(city) {
// 检查城市是否已经添加
return this.selectedCities.some(selectedCity => selectedCity.areaId == city.areaId);
},
removeCity(index) {
// 移除已选择的城市
this.selectedCities.splice(index, 1);
},
confirmSelection() {
// 确认选择并关闭模态窗口
this.form.businessCity = this.selectedCities.map(city => city.areaId).join(',');
this.form.businessCityByName = this.selectedCities.map(city => city.name).join(',');
this.showModal = false;
},
getAreaList() {
listArea().then(response => {
this.cityList = this.buildTree(response.data);
});
},
buildTree(data) {
let tree = [];
let map = {};
data.forEach(node => {
map[node.areaId] = node;
node.children = [];
});
// 将 全国 的节点移到最前面
if (map[0]) {
tree.push(map[0]);
delete map[0];
}
data.forEach(node => {
if (node.parentId != 0) {
const parent = map[node.parentId];
if (parent) {
parent.children.push(node);
}
} else if (node.areaId != 0) {
tree.push(node);
}
});
return tree;
},
/** 查询产品信息列表 */
getList() {
this.loading = true;
this.queryParams.selectByBroker = "1";
pageListInfo(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.infoList = response.rows;
this.total = response.total;
this.loading = false;
}).catch(e => {
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
id: null,
productName: null,
simpleName: null,
productType: null,
productSubtype: null,
maxAmount: null,
interestRateBegin: null,
interestRateEnd: null,
productIntro: null,
productDetail: null,
listBegin: null,
listEnd: null,
status: null,
remark: null,
maxAmountBegin: null,
maxAmountEnd: null,
};
this.resetForm("form");
},
//排序
handleSortChange(col) {
this.$sortBy(col, this.queryParams);
this.getList();
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.queryParams.maxAmountBegin = undefined;
this.queryParams.maxAmountEnd = undefined;
this.queryParams.interestRateEnd = undefined;
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id);
this.names = selection.map(item => item.productName);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.getAllInfo();
this.getbrokerList();
this.form.brokerId = this.brokerId;
this.open = true;
// this.isReadOnly = false;
this.title = "添加产品信息";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.getbrokerList();
const id = row.id || this.ids;
var param = {
id: id,
brokerId: this.brokerId
};
getInfoByBroker(param).then(response => {
this.form = response.data;
this.getAllInfo(id);
this.open = true;
this.title = "修改产品信息";
// this.isReadOnly = true;
});
// getInfo(id).then(response => {
// this.form = response.data;
// this.form.brokerId = this.brokerId;
// this.getAllInfo(id);
// this.open = true;
// this.title = "修改产品信息";
// });
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
editByBroker(this.form).then(response => {
if (response.code === 200) {
this.$modal.msgSuccess("保存成功");
this.open = false;
this.getList();
} else {
this.$modal.msgError(response.msg);
}
});
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const rowIds = Array.isArray(row.id) ? row.id : [row.id];
const ids = [...rowIds, ...this.ids];
const names = row.id || this.names;
var param = {
ids: ids,
brokerId: this.brokerId
};
this.$modal.confirm('是否确认移除产品信息为"' + names + '"的数据项?').then(function () {
return delInfoByBroker(param);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
});
},
/** 导出按钮操作 */
handleExport() {
this.download('product/info/export', {
...this.queryParams
}, `产品信息数据_${new Date().getTime()}.xlsx`)
}
}
}
;
</script>
<style scoped>
.add-button {
margin-left: 10px; /* 将添加按钮向右移动 */
}
.section-title {
font-size: 16px;
margin-bottom: 10px;
}
.city-tree-container {
flex: 1;
overflow-y: auto;
max-height: 400px; /* 设置最大高度 */
}
.city-item {
display: flex;
align-items: center;
justify-content: space-between;
margin-right: 10px;
}
.city-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px;
}
.selected-city-list {
list-style: none;
padding: 0;
margin: 0;
max-height: 440px; /* 设置最大高度 */
flex: 1;
overflow-y: auto;
}
.selected-city-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px;
}
</style>