// 当 realReceiveMoney 改变时,handleRealReceiveMoneyChange 方法会被触发,这会强制重新验证 remark 字段。
// 这确保了当 realReceiveMoney 小于 20 时,remark 字段变为必填,而在其他情况下则不必填。
1.关于vue2 antd 视图更新问题
1.一种强制更新
Vue2是通过用Object…defineProperty来设置数据的getter和setter实现对数据和以及视图改变的监听的。对于数组和对象这种引用类型来说,getter和setter无法检测到它们内部的变化。用这种
this.$set(this.form, "fileUrl", urlArr.join(","));
2.如果碰到
a-form :form="form"
form: this.$form.createForm(this),
<a-form :form="form" @submit="handleSubmit">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="上级仓库"
hasFeedback
>
<a-tree-select
:treeData="dataSource"
placeholder="请选择"
:replaceFields="{
title: 'name',
key: 'id',
value: 'id',
children: 'children',
}"
v-decorator="['parentId', { initialValue: formData.parentId }]"
/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="仓库名称"
hasFeedback
>
<a-input
placeholder="仓库名称"
v-decorator="[
'name',
{
initialValue: formData.name,
rules: validatorRules.inputIf.rules,
},
]"
/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="所属机构"
required
>
<vorganTree
v-decorator="[
'orgId',
{
initialValue: formData.orgId,
rules: validatorRules.inputIf.rules,
},
]"
></vorganTree>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol2"
label="位置地点"
>
<div class="disflex">
<a-input
v-decorator="[
'address',
{
initialValue: formData.address,
rules: validatorRules.inputIf.rules,
},
]"
/>
<a-icon type="environment" @click="mapShow(true)" class="mapico" />
<a-button type="link" @click="mapShow(true)">选择地点</a-button>
</div>
</a-form-item>
</a-form>
a-form :form="form"
form: this.$form.createForm(this),
那么使用
this.form.setFieldsValue({ address: val.address })来更新表单的值,以触发视图的更新。
清空的话
this.form.resetFields();
3.通常双向绑定如果不行试试前两种。
2.关于封装好了表格 使用
1.导入
import STable from "@/components/table/";
index.js
import T from "ant-design-vue/es/table/Table";
import get from "lodash.get"
export default {
data() {
return {
needTotalList: [],
selectedRows: [],
selectedRowKeys: [],
localLoading: false,
localDataSource: [],
localPagination: Object.assign({}, T.props.pagination)
};
},
props: Object.assign({}, T.props, {
rowKey: {
type: [String, Function],
default: 'id'
},
data: {
type: Function,
required: true
},
pageNum: {
type: Number,
default: 1
},
pageSize: {
type: Number,
default: 10
},
showSizeChanger: {
type: Boolean,
default: true
},
showAlertInfo: {
type: Boolean,
default: false
},
showPagination: {
default: 'auto'
},
deleteShow: { // 删除键
type: Boolean,
default: false
},
bordered: {
type: Boolean,
default: true
},
}),
watch: {
'localPagination.current'(val) {
this.$router.push({
name: this.$route.name,
params: Object.assign({}, this.$route.params, {
current: val
}),
});
},
pageNum(val) {
Object.assign(this.localPagination, {
current: val
});
},
pageSize(val) {
Object.assign(this.localPagination, {
pageSize: val
});
},
showSizeChanger(val) {
Object.assign(this.localPagination, {
showSizeChanger: val
});
}
},
zzh() {
const that = this
return that;
},
created() {
this.localPagination = ['auto', true].includes(this.showPagination) && Object.assign({}, this.localPagination, {
current: this.pageNum,
pageSize: this.pageSize,
showSizeChanger: this.showSizeChanger
});
this.needTotalList = this.initTotalList(this.columns)
this.loadData();
},
methods: {
loadingShow(value) {
this.localLoading = value
},
refresh() {
var mm = {
current: 1,
total: 0,
size: this.pageSize,
}
this.loadData(mm);
},
deleteRefresh() {
this.loadData()
},
loadData(pagination, filters, sorter) {
this.localLoading = true
var result = this.data(
Object.assign({
current: (pagination && pagination.current) ||
this.localPagination.current,
size: (pagination && pagination.pageSize) ||
this.localPagination.pageSize
},
(sorter && sorter.field && {
sortField: sorter.field
}) || {},
(sorter && sorter.order && {
sortOrder: sorter.order
}) || {}, {
...filters
}
)
);
if (result instanceof Promise) {
result.then(r => {
this.localPagination = Object.assign({}, this.localPagination, {
current: (pagination && pagination.current) ||
this.localPagination.current, // 返回结果中的当前分页数
total: r.totalCount, // 返回结果中的总记录数
showSizeChanger: this.showSizeChanger,
pageSize: (pagination && pagination.pageSize) ||
this.localPagination.pageSize
});
!r.totalCount && ['auto', false].includes(this.showPagination) && (this.localPagination = false)
this.localDataSource = r.data; // 返回结果中的数组数据
this.localLoading = false
});
}
},
initTotalList(columns) {
const totalList = []
columns && columns instanceof Array && columns.forEach(column => {
if (column.needTotal) {
totalList.push({
...column,
total: 0
})
}
})
return totalList
},
updateSelect(selectedRowKeys, selectedRows) {
this.selectedRowKeys = selectedRowKeys
this.selectedRows = selectedRows
let list = this.needTotalList
this.needTotalList = list.map(item => {
return {
...item,
total: selectedRows.reduce((sum, val) => {
let total = sum + get(val, item.dataIndex)
return isNaN(total) ? 0 : total
}, 0)
}
})
},
updateEdit() {
this.selectedRows = []
},
onClearSelected() {
this.selectedRowKeys = []
this.selectedRows = []
this.updateSelect([], [])
this.$emit('emptyData', { selectedRowKeys: [], selectedRows: [] })
this.$emit('onSelect', { selectedRowKeys: [], selectedRows: [] })
},
onDeleteSelected() {
this.$emit('DeleteData')
},
handleRowClick(record) {
const selectedRowKeys = [...this.selectedRowKeys];
const selectedRows = [...this.selectedRows];
const rowKey = typeof this.rowKey === 'function' ? this.rowKey(record) : record[this.rowKey];
const rowIndex = selectedRowKeys.indexOf(rowKey);
if (rowIndex >= 0) {
selectedRowKeys.splice(rowIndex, 1);
selectedRows.splice(rowIndex, 1);
} else {
selectedRowKeys.push(rowKey);
selectedRows.push(record);
}
this.updateSelect(selectedRowKeys, selectedRows);
this.$emit('onSelect', { selectedRowKeys, selectedRows });
},
renderMsg(h) {
const _vm = this
this.that = this
let d = []
return d
},
renderAlert(h) {
return h('span', {
slot: 'message'
}, this.renderMsg(h))
},
},
render(h) {
const _vm = this
let props = {},
localKeys = Object.keys(this.$data);
Object.keys(T.props).forEach(k => {
let localKey = `local${k.substring(0, 1).toUpperCase()}${k.substring(1)}`;
if (localKeys.includes(localKey)) {
return props[k] = _vm[localKey];
}
return props[k] = _vm[k];
})
// 显示信息提示
if (this.showAlertInfo) {
props.rowSelection = {
selectedRowKeys: this.selectedRowKeys,
onChange: (selectedRowKeys, selectedRows) => {
_vm.updateSelect(selectedRowKeys, selectedRows)
_vm.$emit('onSelect', { selectedRowKeys: selectedRowKeys, selectedRows: selectedRows })
}
};
props.customRow = (record) => ({
on: {
click: () => {
_vm.handleRowClick(record);
},
},
});
return h('div', {}, [
h("a-table", {
tag: "component",
attrs: props,
on: {
change: _vm.loadData
},
scopedSlots: this.$scopedSlots
}, this.$slots.default)
]);
}
props.customRow = (record) => ({
on: {
click: () => {
_vm.handleRowClick(record);
},
},
});
return h("a-table", {
tag: "component",
attrs: props,
on: {
change: _vm.loadData
},
scopedSlots: this.$scopedSlots
}, this.$slots.default);
},
};
使用
<s-table
ref="tableAssets"
size="default"
:rowKey="(record) => record.id"
:columns="columns1"
:data="loadDataListAssets"
:showAlertInfo="true"
@onSelect="onChangeAssetsList"
></s-table>
loadDataListAssets: (parameter) => {
return getUserPage(Object.assign(parameter, this.listAssetsParam)).then(
(res) => {
var mm = { data: [] };
mm.size = res.data.size;
mm.current = res.data.current;
mm.totalCount = res.data.total;
mm.totalPage = res.data.pages;
mm.data = res.data.records;
return mm;
}
);
},
onChangeAssetsList(row) {
console.log(row);
let self = this;
self.personList = [];
let arr = [...new Set([...row.selectedRows])];
let AssetsListRow = [
...new Set([...self.AssetsListRow.concat(arr), ...arr]),
];
self.AssetsListRow = AssetsListRow.filter((item) =>
row.selectedRowKeys.includes(item.id)
);
self.personList = [...new Set([...self.AssetsListRow, ...arr])];
// self.personList = [...new Set([...self.personList, ...arr])];
// const strings = self.personList.map((item) => JSON.stringify(item));
// const removeDupList = Array.from(new Set(strings));
// const result = removeDupList.map((item) => JSON.parse(item));
// self.personList = result;
},
有slot使用
<s-table ref="tableAssets2" size="default" :columns="columns2" :data="loadDataListAssets2">
<span slot="action" slot-scope="text, record" class="flx-row-c-c">
<div>
<a @click="handleDel(record)">删除</a>
</div>
</span>
</s-table>
3.关于单选封装好的组件使用
<j-select-supplier
v-decorator="['supplierId']"
:multiple="false"
@accountData="accountData2"
></j-select-supplier>
import JSelectSupplier from "@/components/jeecgbiz/JSelectSupplier";
accountData2(e) {
if (e.length > 0) {
this.editform.supplierName = e[0].name;
this.editform.supplierId = e[0].id;
} else {
this.editform.supplierName = "";
this.editform.supplierId = "";
}
console.log(e);
},
<template>
<!-- 定义在这里的参数都是不可在外部覆盖的,防止出现问题 -->
<j-select-biz-component-two
:value="value"
:ellipsisLength="25"
:listUrl="url.list"
:columns="columns"
:multiple="false"
v-on="$listeners"
v-bind="attrs"
@commitData="commitData"
/>
</template>
<script>
import JSelectBizComponentTwo from "./JSelectBizComponentTwo";
export default {
name: "JSelectSupplier",
components: { JSelectBizComponentTwo },
props: ["value"],
data() {
return {
url: { list: "/asset/supplierinfo/page" },
columns: [
{ title: "供应商", align: "center", dataIndex: "name" },
{
title: "联系人",
align: "center",
dataIndex: "linkman",
},
{
title: "联系电话",
align: "center",
dataIndex: "phone",
},
],
// 定义在这里的参数都是可以在外部传递覆盖的,可以更灵活的定制化使用的组件
default: {
name: "供应商",
width: "80%",
displayKey: "name",
returnKeys: ["id", "name"],
rowKey: "id",
valueKey: "id",
queryParamText: "供应商名称", //左侧搜索框名称
queryParamCode: "name", //左侧搜索框字段名
},
};
},
computed: {
attrs() {
return Object.assign(this.default, this.$attrs);
},
},
methods: {
// 提交数据
commitData(e) {
console.log(e);
this.$emit("accountData", e);
},
},
};
</script>
<style lang="less" scoped></style>
外层也就是index
<template>
<a-row class="j-select-biz-component-box" type="flex" :gutter="8">
<a-col class="left" :class="{'full': !buttons}">
<slot name="left">
<a-select
mode="multiple"
:placeholder="placeholder"
v-model="selectValue"
:options="selectOptions"
allowClear
:disabled="disabled"
:open="selectOpen"
style="width: 100%;"
@dropdownVisibleChange="handleDropdownVisibleChange"
@click.native="visible=(buttons?visible:true)"
/>
</slot>
</a-col>
<a-col v-if="buttons" class="right">
<a-button type="primary" icon="search" :disabled="disabled" @click="visible=true">{{selectButtonText}}</a-button>
</a-col>
<j-select-biz-component-modal
v-model="selectValue"
:visible.sync="visible"
v-bind="modalProps"
:multiple="multiple"
@options="handleOptions"
@commitData="commitData"
/>
</a-row>
</template>
<script>
import JSelectBizComponentModal from './JSelectBizComponentModal'
export default {
name: 'JSelectBizComponent',
components: { JSelectBizComponentModal },
props: {
value: {
type: String,
default: ''
},
/** 是否返回 id,默认 false,返回 code */
returnId: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: '请选择'
},
disabled: {
type: Boolean,
default: false
},
// 是否支持多选,默认 true
multiple: {
type: Boolean,
default: true
},
// 是否显示按钮,默认 true
buttons: {
type: Boolean,
default: true
},
// 显示的 Key
displayKey: {
type: String,
default: null
},
// 返回的 key
returnKeys: {
type: Array,
default: () => ['id', 'id']
},
// 选择按钮文字
selectButtonText: {
type: String,
default: '选择'
},
},
data() {
return {
selectValue: [],
selectOptions: [],
dataSourceMap: {},
visible: false,
selectOpen: false,
}
},
computed: {
valueKey() {
return this.returnId ? this.returnKeys[0] : this.returnKeys[1]
},
modalProps() {
return Object.assign({
valueKey: this.valueKey,
multiple: this.multiple,
returnKeys: this.returnKeys,
displayKey: this.displayKey || this.valueKey
}, this.$attrs)
},
},
watch: {
value: {
immediate: true,
handler(val) {
console.log('cake撒',val)
if (val) {
this.selectValue = val.split(',')
} else {
this.selectValue = []
}
}
},
selectValue: {
deep: true,
handler(val) {
console.log(this.materialUseTime)
let rows = val.map(key => this.dataSourceMap[key])
this.$emit('select', rows)
let data = val.join(',')
this.$emit('input', data)
this.$emit('change', data)
}
}
},
methods: {
commitData(e) {
this.$emit('commitData',e)
},
handleOptions(options, dataSourceMap) {
this.selectOptions = options
this.dataSourceMap = dataSourceMap
},
handleDropdownVisibleChange() {
// 解决antdv自己的bug —— open 设置为 false 了,点击后还是添加了 open 样式,导致点击事件失效
this.selectOpen = true
this.$nextTick(() => {
this.selectOpen = false
})
},
}
}
</script>
<style lang="less" scoped>
.j-select-biz-component-box {
@width: 82px;
.left {
width: calc(100% - @width - 8px);
}
.right {
width: @width;
}
.full {
width: 100%;
}
/deep/ .ant-select-search__field {
display: none !important;
}
}
</style>
内层
<template>
<a-modal
centered
:title="name + '选择'"
:width="width"
:visible="visible"
@ok="handleOk"
@cancel="close"
cancelText="关闭"
>
<a-row :gutter="18">
<a-col :span="16">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24">
<a-col :span="14">
<a-form-item :label="queryParamText || name">
<a-input
v-model="queryParam[queryParamCode || valueKey]"
:placeholder="'请输入' + (queryParamText || name)"
@pressEnter="searchQuery"
/>
</a-form-item>
</a-col>
<a-col :span="8">
<span
style="float: left; overflow: hidden"
class="table-page-search-submitButtons"
>
<a-button type="primary" @click="searchQuery" icon="search"
>查询</a-button
>
<a-button
type="primary"
@click="searchReset"
icon="reload"
style="margin-left: 8px"
>重置</a-button
>
</span>
</a-col>
</a-row>
</a-form>
</div>
<a-table
size="small"
bordered
:rowKey="rowKey"
:columns="innerColumns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:scroll="{ y: 240 }"
:rowSelection="{
selectedRowKeys,
onChange: onSelectChange,
type: multiple ? 'checkbox' : 'radio',
width: '60px',
}"
:customRow="customRowFn"
@change="handleTableChange"
>
</a-table>
</a-col>
<a-col :span="8">
<a-card
:title="'已选中的' + name"
:bordered="false"
:head-style="{ padding: 0 }"
:body-style="{ padding: 0 }"
>
<a-table
size="small"
:rowKey="rowKey"
bordered
v-bind="selectedTable"
>
<span slot="action" slot-scope="text, record, index">
<a @click="handleDeleteSelected(record, index)">删除</a>
</span>
</a-table>
</a-card>
</a-col>
</a-row>
</a-modal>
</template>
<script>
// import { getAction } from '@/api/manage'
import Ellipsis from "@/components/Ellipsis";
import { JeecgListMixin } from "@/mixins/JeecgListMixin";
import { cloneObject, pushIfNotExist } from "@/utils/util";
export default {
name: "JSelectBizComponentModal",
mixins: [JeecgListMixin],
components: { Ellipsis },
props: {
value: {
type: Array,
default: () => [],
},
visible: {
type: Boolean,
default: false,
},
valueKey: {
type: String,
required: true,
},
multiple: {
type: Boolean,
default: true,
},
width: {
type: [Number, String],
default: "80%",
},
name: {
type: String,
default: "",
},
listUrl: {
type: String,
required: true,
default: "",
},
// 根据 value 获取显示文本的地址,例如存的是 username,可以通过该地址获取到 realname
valueUrl: {
type: String,
default: "",
},
displayKey: {
type: String,
default: null,
},
columns: {
type: Array,
required: true,
default: () => [],
},
// 查询条件Code
queryParamCode: {
type: String,
default: null,
},
// 查询条件文字
queryParamText: {
type: String,
default: null,
},
rowKey: {
type: String,
default: "id",
},
// 过长裁剪长度,设置为 -1 代表不裁剪
ellipsisLength: {
type: Number,
default: 12,
},
},
data() {
return {
innerValue: [],
// 已选择列表
selectedTable: {
pagination: false,
scroll: { y: 240 },
columns: [
{
...this.columns[0],
width: this.columns[0].widthRight || this.columns[0].width,
},
{
...this.columns[1],
width: this.columns[1].widthRight || this.columns[1].width,
},
{
title: "操作",
dataIndex: "action",
align: "center",
width: 60,
scopedSlots: { customRender: "action" },
},
],
dataSource: [],
},
renderEllipsis: (value) => (
<ellipsis length={this.ellipsisLength}>{value}</ellipsis>
),
url: { list: this.listUrl },
/* 分页参数 */
ipagination: {
current: 1,
pageSize: 5,
pageSizeOptions: ["5", "10", "20", "30"],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " 共" + total + "条";
},
showQuickJumper: true,
showSizeChanger: true,
total: 0,
},
options: [],
dataSourceMap: {},
};
},
computed: {
// 表头
innerColumns() {
let columns = cloneObject(this.columns);
columns.forEach((column) => {
// 给所有的列加上过长裁剪
if (this.ellipsisLength !== -1) {
column.customRender = (text) => this.renderEllipsis(text);
}
});
return columns;
},
},
watch: {
value: {
deep: true,
immediate: true,
handler(val) {
console.log(val);
this.innerValue = cloneObject(val);
this.selectedRowKeys = [];
this.valueWatchHandler(val);
this.queryOptionsByValue(val);
},
},
dataSource: {
deep: true,
handler(val) {
// 重置之后key恢复
this.emitOptions(val);
this.valueWatchHandler(this.innerValue);
},
},
selectedRowKeys: {
immediate: true,
deep: true,
handler(val) {
this.selectedTable.dataSource = val.map((key) => {
for (let data of this.dataSource) {
if (data[this.rowKey] === key) {
pushIfNotExist(this.innerValue, data[this.valueKey]);
return data;
}
}
for (let data of this.selectedTable.dataSource) {
if (data[this.rowKey] === key) {
pushIfNotExist(this.innerValue, data[this.valueKey]);
return data;
}
}
console.warn("未找到选择的行信息,key:" + key);
return {};
});
},
},
},
methods: {
/** 关闭弹窗 */
close() {
this.$emit("update:visible", false);
},
valueWatchHandler(val) {
console.log(val);
val.forEach((item) => {
this.dataSource
.concat(this.selectedTable.dataSource)
.forEach((data) => {
if (data[this.valueKey] === item) {
pushIfNotExist(this.selectedRowKeys, data[this.rowKey]);
}
});
});
},
queryOptionsByValue(value) {
console.log(value);
if (!value || value.length === 0) {
return;
}
// 判断options是否存在value,如果已存在数据就不再请求后台了
let notExist = false;
for (let val of value) {
let find = false;
for (let option of this.options) {
if (val === option.value) {
find = true;
break;
}
}
if (!find) {
notExist = true;
break;
}
}
if (!notExist) return;
// listDepartUser( {
// // 这里最后加一个 , 的原因是因为无论如何都要使用 in 查询,防止后台进行了模糊匹配,导致查询结果不准确
// // [this.valueKey]: value.join(',') + ',',
// pageNo: 1,
// pageSize: value.length
// }).then((res) => {
// if (res.success) {
// let dataSource = res.result
// if (!(dataSource instanceof Array)) {
// dataSource = res.result.records
// }
// this.emitOptions(dataSource, (data) => {
// pushIfNotExist(this.innerValue, data[this.valueKey])
// pushIfNotExist(this.selectedRowKeys, data[this.rowKey])
// pushIfNotExist(this.selectedTable.dataSource, data, this.rowKey)
// })
// }
// })
},
emitOptions(dataSource, callback) {
dataSource.forEach((data) => {
let key = data[this.valueKey];
this.dataSourceMap[key] = data;
pushIfNotExist(
this.options,
{ label: data[this.displayKey || this.valueKey], value: key },
"value"
);
typeof callback === "function" ? callback(data) : "";
});
this.$emit("options", this.options, this.dataSourceMap);
},
/** 完成选择 */
handleOk() {
let value = this.selectedTable.dataSource.map(
(data) => data[this.valueKey]
);
this.$emit("input", value);
this.$emit("commitData", this.selectedTable.dataSource);
this.close();
},
/** 删除已选择的 */
handleDeleteSelected(record, index) {
this.selectionRows.splice(
this.selectedRowKeys.indexOf(record[this.rowKey]),
1
);
this.selectedRowKeys.splice(
this.selectedRowKeys.indexOf(record[this.rowKey]),
1
);
this.selectedTable.dataSource.splice(index, 1);
console.log(this.selectedRowKeys, this.selectionRows);
},
customRowFn(record) {
return {
on: {
click: () => {
let key = record[this.rowKey];
if (!this.multiple) {
this.selectedRowKeys = [key];
this.selectedTable.dataSource = [record];
} else {
let index = this.selectedRowKeys.indexOf(key);
if (index === -1) {
this.selectedRowKeys.push(key);
this.selectedTable.dataSource.push(record);
} else {
this.handleDeleteSelected(record, index);
}
}
},
},
};
},
},
};
</script>
<style lang="less" scoped>
</style>
JeecgListMixin的方法
/**
* 新增修改完成调用 modalFormOk方法 编辑弹框组件ref定义为modalForm
* 高级查询按钮调用 superQuery方法 高级查询组件ref定义为superQueryModal
* data中url定义 list为查询列表 delete为删除单条记录 deleteBatch为批量删除
*/
import { filterObj } from "@/utils/util";
import { deleteAction, getAction, downFile, getFileAccessHttpUrl } from "@/api/manage";
export const JeecgListMixin = {
data() {
return {
/* 查询条件-请不要在queryParam中声明非字符串值的属性 */
queryParam: {},
/* 数据源 */
dataSource: [],
/* 分页参数 */
ipagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ["10", "20", "30"],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " 共" + total + "条";
},
showQuickJumper: true,
showSizeChanger: true,
total: 0,
},
/* 排序参数 */
isorter: {
column: "createTime",
order: "desc",
},
/* 筛选参数 */
filters: {},
/* table加载状态 */
loading: false,
/* table选中keys*/
selectedRowKeys: [],
/* table选中records*/
selectionRows: [],
/* 查询折叠 */
toggleSearchStatus: false,
/* 高级查询条件生效状态 */
superQueryFlag: false,
/* 高级查询条件 */
superQueryParams: "",
/** 高级查询拼接方式 */
superQueryMatchType: "and",
};
},
created() {
if (!this.disableMixinCreated) {
console.log(" -- mixin created -- ");
this.loadData();
//初始化字典配置 在自己页面定义
this.initDictConfig();
}
},
computed: {},
methods: {
loadData(arg) {
if (!this.url.list) {
this.$message.error("请设置url.list属性!");
return;
}
//加载数据 若传入参数1则加载第一页的内容
if (arg === 1) {
this.ipagination.current = 1;
}
var params = this.getQueryParams(); //查询条件
this.loading = true;
getAction(this.url.list, params)
.then((res) => {
if (res.ok) {
//update-begin---author:zhangyafei Date:20201118 for:适配不分页的数据列表------------
this.dataSource = res.data.records || res.data;
if (res.data.total) {
this.ipagination.total = res.data.total;
} else {
this.ipagination.total = 0;
}
//update-end---author:zhangyafei Date:20201118 for:适配不分页的数据列表------------
} else {
this.$message.warning(res.msg);
}
})
.finally(() => {
this.loading = false;
});
},
initDictConfig() {
console.log("--这是一个假的方法!");
},
handleSuperQuery(params, matchType) {
//高级查询方法
if (!params) {
this.superQueryParams = "";
this.superQueryFlag = false;
} else {
this.superQueryFlag = true;
this.superQueryParams = JSON.stringify(params);
this.superQueryMatchType = matchType;
}
this.loadData(1);
},
getQueryParams() {
//获取查询条件
let sqp = {};
if (this.superQueryParams) {
sqp["superQueryParams"] = encodeURI(this.superQueryParams);
sqp["superQueryMatchType"] = this.superQueryMatchType;
}
var param = Object.assign(sqp, this.queryParam, this.isorter, this.filters);
// param.field = this.getQueryField();
param.current = this.ipagination.current;
param.size = this.ipagination.pageSize;
return filterObj(param);
},
getQueryField() {
//TODO 字段权限控制
var str = "id,";
this.columns.forEach(function (value) {
str += "," + value.dataIndex;
});
return str;
},
onSelectChange(selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectionRows;
console.log(selectedRowKeys, selectionRows);
},
onClearSelected() {
this.selectedRowKeys = [];
this.selectionRows = [];
},
searchQuery() {
this.loadData(1);
},
superQuery() {
this.$refs.superQueryModal.show();
},
searchReset() {
this.queryParam = {};
this.loadData(1);
},
batchDel: function () {
if (!this.url.deleteBatch) {
this.$message.error("请设置url.deleteBatch属性!");
return;
}
if (this.selectedRowKeys.length <= 0) {
this.$message.warning("请选择一条记录!");
return;
} else {
var ids = "";
for (var a = 0; a < this.selectedRowKeys.length; a++) {
ids += this.selectedRowKeys[a] + ",";
}
var that = this;
this.$confirm({
title: "确认删除",
content: "是否删除选中数据?",
onOk: function () {
that.loading = true;
deleteAction(that.url.deleteBatch, { ids: ids })
.then((res) => {
if (res.success) {
//重新计算分页问题
that.reCalculatePage(that.selectedRowKeys.length);
that.$message.success(res.message);
that.loadData();
that.onClearSelected();
} else {
that.$message.warning(res.message);
}
})
.finally(() => {
that.loading = false;
});
},
});
}
},
handleDelete: function (id) {
if (!this.url.delete) {
this.$message.error("请设置url.delete属性!");
return;
}
var that = this;
deleteAction(`${that.url.delete}/${id}`, { id: id }).then((res) => {
if (res.ok) {
//重新计算分页问题
that.reCalculatePage(1);
that.$message.success("操作成功");
that.loadData();
} else {
that.$message.warning(res.msg);
}
});
},
reCalculatePage(count) {
//总数量-count
let total = this.ipagination.total - count;
//获取删除后的分页数
let currentIndex = Math.ceil(total / this.ipagination.pageSize);
//删除后的分页数<所在当前页
if (currentIndex < this.ipagination.current) {
this.ipagination.current = currentIndex;
}
console.log("currentIndex", currentIndex);
},
handleEdit: function (record) {
this.$refs.modalForm.edit(record);
this.$refs.modalForm.title = "编辑";
this.$refs.modalForm.disableSubmit = false;
},
handleAdd: function () {
this.$refs.modalForm.add();
this.$refs.modalForm.title = "新增";
this.$refs.modalForm.disableSubmit = false;
},
handleTableChange(pagination, filters, sorter) {
//分页、排序、筛选变化时触发
//TODO 筛选
console.log(pagination);
if (Object.keys(sorter).length > 0) {
// this.isorter.column = sorter.field;
this.isorter.order = "ascend" == sorter.order ? "asc" : "desc";
}
this.ipagination = pagination;
this.loadData();
},
handleToggleSearch() {
this.toggleSearchStatus = !this.toggleSearchStatus;
},
// 给popup查询使用(查询区域不支持回填多个字段,限制只返回一个字段)
getPopupField(fields) {
return fields.split(",")[0];
},
modalFormOk() {
// 新增/修改 成功时,重载列表
this.loadData();
//清空列表选中
this.onClearSelected();
},
handleDetail: function (record) {
this.$refs.modalForm.edit(record);
this.$refs.modalForm.title = "详情";
this.$refs.modalForm.disableSubmit = true;
},
/* 导出 */
handleExportXls2() {
let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
let url = `${window._CONFIG["domianURL"]}/${this.url.exportXlsUrl}?paramsStr=${paramsStr}`;
window.location.href = url;
},
handleExportXls(fileName) {
if (!fileName || typeof fileName != "string") {
fileName = "导出文件";
}
let param = this.getQueryParams();
if (this.selectedRowKeys && this.selectedRowKeys.length > 0) {
param["selections"] = this.selectedRowKeys.join(",");
}
console.log("导出参数", param);
downFile(this.url.exportXlsUrl, param).then((data) => {
if (!data) {
this.$message.warning("文件下载失败");
return;
}
if (typeof window.navigator.msSaveBlob !== "undefined") {
window.navigator.msSaveBlob(new Blob([data], { type: "application/vnd.ms-excel" }), fileName + ".xls");
} else {
console.log(data);
let url = window.URL.createObjectURL(new Blob([data.data], { type: "application/vnd.ms-excel" }));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
link.setAttribute("download", fileName + ".xls");
document.body.appendChild(link);
link.click();
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
}
});
},
/* 图片预览 */
getImgView(text) {
if (text && text.indexOf(",") > 0) {
text = text.substring(0, text.indexOf(","));
}
return getFileAccessHttpUrl(text);
},
/* 文件下载 */
// update--autor:lvdandan-----date:20200630------for:修改下载文件方法名uploadFile改为downloadFile------
downloadFile(text) {
if (!text) {
this.$message.warning("未知的文件");
return;
}
if (text.indexOf(",") > 0) {
text = text.substring(0, text.indexOf(","));
}
let url = getFileAccessHttpUrl(text);
window.open(url);
},
},
};
Ellipsis的方法
import Ellipsis from './Ellipsis'
export default Ellipsis
Ellipsis.vue
<script>
import { cutStrByFullLength, getStrFullLength } from '@/components/_util/StringUtil'
export default {
name: 'Ellipsis',
props: {
prefixCls: {
type: String,
default: 'ant-pro-ellipsis'
},
tooltip: {
type: Boolean,
default: true,
},
length: {
type: Number,
default: 25,
},
lines: {
type: Number,
default: 1
},
fullWidthRecognition: {
type: Boolean,
default: false
}
},
methods: {},
render() {
const { tooltip, length } = this.$props
let text = ''
// 处理没有default插槽时的特殊情况
if (this.$slots.default) {
text = this.$slots.default.map(vNode => vNode.text).join('')
}
// 判断是否显示 tooltip
if (tooltip && getStrFullLength(text) > length) {
return (
<a-tooltip>
<template slot="title">{text}</template>
<span>{cutStrByFullLength(text, this.length) + '…'}</span>
</a-tooltip>
)
} else {
return (<span>{text}</span>)
}
}
}
</script>
4.关于封装好的复选表格
<j-select-contract
:trigger-change="true"
v-decorator="['purchaseContractIds']"
customReturnField="purchaseContractIds"
@accountData="changeContract"
:multiple="true"
:status="2"
></j-select-contract>
import JSelectContract from "@/components/jeecgbiz/JSelectContract";
<template>
<!-- 定义在这里的参数都是不可在外部覆盖的,防止出现问题 -->
<j-select-biz-component
:value="value"
:ellipsisLength="25"
:listUrl="url.list"
:columns="columns"
:multiple="multiple"
v-on="$listeners"
v-bind="attrs"
@commitData="commitData"
/>
</template>
<script>
import JSelectBizComponent from "./JSelectBizComponent";
export default {
name: "JSelectContract",
components: { JSelectBizComponent },
props: ["value", "multiple"],
data() {
return {
url: { list: "/asset/purchasecontract/page?contractStatus=2&isAllTake=0" },
columns: [
{ title: "合同单据号", align: "center", width: "25%", widthRight: "70%", dataIndex: "purchaseContractNo" },
{ title: "订购时间", align: "center", width: "25%", dataIndex: "orderDate" },
{ title: "采购员", align: "center", width: "20%", dataIndex: "purchasePersonName" },
{ title: "采购部门", align: "center", width: "20%", dataIndex: "organName" },
],
// 定义在这里的参数都是可以在外部传递覆盖的,可以更灵活的定制化使用的组件
default: {
name: "采购合同",
width: 1200,
displayKey: "purchaseContractNo",
returnKeys: ["id", "purchaseContractNo", "organName", "organId"],
queryParamText: "合同单据号",
queryParamCode: "purchaseContractNo",
},
};
},
computed: {
attrs() {
return Object.assign(this.default, this.$attrs);
},
},
methods: {
// 提交数据
commitData(e) {
this.$emit("accountData", e);
},
},
};
</script>
<style lang="less" scoped></style>
index外层
<template>
<a-row class="j-select-biz-component-box" type="flex" :gutter="8">
<a-col class="left" :class="{'full': !buttons}">
<slot name="left">
<a-select
mode="multiple"
:placeholder="placeholder"
v-model="selectValue"
:options="selectOptions"
allowClear
:disabled="disabled"
:open="selectOpen"
style="width: 100%;"
@dropdownVisibleChange="handleDropdownVisibleChange"
@click.native="visible=(buttons?visible:true)"
/>
</slot>
</a-col>
<a-col v-if="buttons" class="right">
<a-button type="primary" icon="search" :disabled="disabled" @click="visible=true">{{selectButtonText}}</a-button>
</a-col>
<j-select-biz-component-modal
v-model="selectValue"
:visible.sync="visible"
v-bind="modalProps"
:multiple="multiple"
@options="handleOptions"
@commitData="commitData"
/>
</a-row>
</template>
<script>
import JSelectBizComponentModal from './JSelectBizComponentModal'
export default {
name: 'JSelectBizComponent',
components: { JSelectBizComponentModal },
props: {
value: {
type: String,
default: ''
},
/** 是否返回 id,默认 false,返回 code */
returnId: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: '请选择'
},
disabled: {
type: Boolean,
default: false
},
// 是否支持多选,默认 true
multiple: {
type: Boolean,
default: true
},
// 是否显示按钮,默认 true
buttons: {
type: Boolean,
default: true
},
// 显示的 Key
displayKey: {
type: String,
default: null
},
// 返回的 key
returnKeys: {
type: Array,
default: () => ['id', 'id']
},
// 选择按钮文字
selectButtonText: {
type: String,
default: '选择'
},
},
data() {
return {
selectValue: [],
selectOptions: [],
dataSourceMap: {},
visible: false,
selectOpen: false,
}
},
computed: {
valueKey() {
return this.returnId ? this.returnKeys[0] : this.returnKeys[1]
},
modalProps() {
return Object.assign({
valueKey: this.valueKey,
multiple: this.multiple,
returnKeys: this.returnKeys,
displayKey: this.displayKey || this.valueKey
}, this.$attrs)
},
},
watch: {
value: {
immediate: true,
handler(val) {
console.log('cake撒',val)
if (val) {
this.selectValue = val.split(',')
} else {
this.selectValue = []
}
}
},
selectValue: {
deep: true,
handler(val) {
console.log(this.materialUseTime)
let rows = val.map(key => this.dataSourceMap[key])
this.$emit('select', rows)
let data = val.join(',')
this.$emit('input', data)
this.$emit('change', data)
}
}
},
methods: {
commitData(e) {
this.$emit('commitData',e)
},
handleOptions(options, dataSourceMap) {
this.selectOptions = options
this.dataSourceMap = dataSourceMap
},
handleDropdownVisibleChange() {
// 解决antdv自己的bug —— open 设置为 false 了,点击后还是添加了 open 样式,导致点击事件失效
this.selectOpen = true
this.$nextTick(() => {
this.selectOpen = false
})
},
}
}
</script>
<style lang="less" scoped>
.j-select-biz-component-box {
@width: 82px;
.left {
width: calc(100% - @width - 8px);
}
.right {
width: @width;
}
.full {
width: 100%;
}
/deep/ .ant-select-search__field {
display: none !important;
}
}
</style>
内层
<template>
<a-modal
centered
:title="name + '选择'"
:width="width"
:visible="visible"
@ok="handleOk"
@cancel="close"
cancelText="关闭"
>
<a-row :gutter="18">
<a-col :span="16">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form :labelCol="{ span: 5 }" :wrapperCol="{ span: 18, offset: 1 }">
<a-row :gutter="24">
<a-col :span="14">
<a-form-item :label="queryParamText || name">
<a-input
v-model="queryParam[queryParamCode || valueKey]"
:placeholder="'请输入' + (queryParamText || name)"
@pressEnter="searchQuery"
/>
</a-form-item>
</a-col>
<a-col :span="8">
<span
style="float: left; overflow: hidden"
class="table-page-search-submitButtons"
>
<a-button type="primary" @click="searchQuery" icon="search"
>查询</a-button
>
<a-button
type="primary"
@click="searchReset"
icon="reload"
style="margin-left: 8px"
>重置</a-button
>
</span>
</a-col>
</a-row>
</a-form>
</div>
<a-table
size="small"
bordered
:rowKey="rowKey"
:columns="innerColumns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:scroll="{ y: 240 }"
:rowSelection="{
selectedRowKeys,
onChange: onSelectChange,
type: multiple ? 'checkbox' : 'radio',
}"
:customRow="customRowFn"
@change="handleTableChange"
>
</a-table>
</a-col>
<a-col :span="8">
<a-card
:title="'已选' + name"
:bordered="false"
:head-style="{ padding: 0 }"
:body-style="{ padding: 0 }"
>
<a-table
size="small"
:rowKey="rowKey"
bordered
v-bind="selectedTable"
>
<span slot="action" slot-scope="text, record, index">
<a @click="handleDeleteSelected(record, index)">删除</a>
</span>
</a-table>
</a-card>
</a-col>
</a-row>
</a-modal>
</template>
<script>
// import { getAction } from '@/api/manage'
import Ellipsis from "@/components/Ellipsis";
import { JeecgListMixin } from "@/mixins/JeecgListMixin";
import { cloneObject, pushIfNotExist } from "@/utils/util";
import { listDepartUser } from "@/api/apis";
export default {
name: "JSelectBizComponentModal",
mixins: [JeecgListMixin],
components: { Ellipsis },
props: {
value: {
type: Array,
default: () => [],
},
visible: {
type: Boolean,
default: false,
},
valueKey: {
type: String,
required: true,
},
multiple: {
type: Boolean,
default: true,
},
width: {
type: Number,
default: 900,
},
name: {
type: String,
default: "",
},
listUrl: {
type: String,
required: true,
default: "",
},
// 根据 value 获取显示文本的地址,例如存的是 username,可以通过该地址获取到 realname
valueUrl: {
type: String,
default: "",
},
displayKey: {
type: String,
default: null,
},
columns: {
type: Array,
required: true,
default: () => [],
},
// 查询条件Code
queryParamCode: {
type: String,
default: null,
},
// 查询条件文字
queryParamText: {
type: String,
default: null,
},
rowKey: {
type: String,
default: "id",
},
// 过长裁剪长度,设置为 -1 代表不裁剪
ellipsisLength: {
type: Number,
default: 12,
},
},
data() {
return {
innerValue: [],
// 已选择列表
selectedTable: {
pagination: false,
scroll: { y: 240 },
columns: [
{
...this.columns[0],
width: this.columns[0].widthRight || this.columns[0].width,
},
{
title: "操作",
dataIndex: "action",
align: "center",
width: 60,
scopedSlots: { customRender: "action" },
},
],
dataSource: [],
},
renderEllipsis: (value) => (
<ellipsis length={this.ellipsisLength}>{value}</ellipsis>
),
url: { list: this.listUrl },
/* 分页参数 */
ipagination: {
current: 1,
pageSize: 5,
pageSizeOptions: ["5", "10", "20", "30"],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " 共" + total + "条";
},
showQuickJumper: true,
showSizeChanger: true,
total: 0,
},
options: [],
dataSourceMap: {},
};
},
computed: {
// 表头
innerColumns() {
let columns = cloneObject(this.columns);
columns.forEach((column) => {
// 给所有的列加上过长裁剪
if (this.ellipsisLength !== -1) {
column.customRender = (text) => this.renderEllipsis(text);
}
});
return columns;
},
},
watch: {
value: {
deep: true,
immediate: true,
handler(val) {
console.log(val);
this.innerValue = cloneObject(val);
this.selectedRowKeys = [];
this.valueWatchHandler(val);
this.queryOptionsByValue(val);
},
},
dataSource: {
deep: true,
handler(val) {
// 重置之后key恢复
this.emitOptions(val);
this.valueWatchHandler(this.innerValue);
},
},
selectedRowKeys: {
immediate: true,
deep: true,
handler(val) {
this.selectedTable.dataSource = val.map((key) => {
for (let data of this.dataSource) {
if (data[this.rowKey] === key) {
pushIfNotExist(this.innerValue, data[this.valueKey]);
return data;
}
}
for (let data of this.selectedTable.dataSource) {
if (data[this.rowKey] === key) {
pushIfNotExist(this.innerValue, data[this.valueKey]);
return data;
}
}
console.warn("未找到选择的行信息,key:" + key);
return {};
});
},
},
},
methods: {
/** 关闭弹窗 */
close() {
this.$emit("update:visible", false);
},
valueWatchHandler(val) {
console.log(val);
val.forEach((item) => {
this.dataSource
.concat(this.selectedTable.dataSource)
.forEach((data) => {
if (data[this.valueKey] === item) {
pushIfNotExist(this.selectedRowKeys, data[this.rowKey]);
}
});
});
},
queryOptionsByValue(value) {
console.log(value);
if (!value || value.length === 0) {
return;
}
// 判断options是否存在value,如果已存在数据就不再请求后台了
let notExist = false;
for (let val of value) {
let find = false;
for (let option of this.options) {
if (val === option.value) {
find = true;
break;
}
}
if (!find) {
notExist = true;
break;
}
}
if (!notExist) return;
// listDepartUser( {
// // 这里最后加一个 , 的原因是因为无论如何都要使用 in 查询,防止后台进行了模糊匹配,导致查询结果不准确
// // [this.valueKey]: value.join(',') + ',',
// pageNo: 1,
// pageSize: value.length
// }).then((res) => {
// if (res.success) {
// let dataSource = res.result
// if (!(dataSource instanceof Array)) {
// dataSource = res.result.records
// }
// this.emitOptions(dataSource, (data) => {
// pushIfNotExist(this.innerValue, data[this.valueKey])
// pushIfNotExist(this.selectedRowKeys, data[this.rowKey])
// pushIfNotExist(this.selectedTable.dataSource, data, this.rowKey)
// })
// }
// })
},
emitOptions(dataSource, callback) {
dataSource.forEach((data) => {
let key = data[this.valueKey];
this.dataSourceMap[key] = data;
pushIfNotExist(
this.options,
{ label: data[this.displayKey || this.valueKey], value: key },
"value"
);
typeof callback === "function" ? callback(data) : "";
});
this.$emit("options", this.options, this.dataSourceMap);
},
/** 完成选择 */
handleOk() {
let value = this.selectedTable.dataSource.map(
(data) => data[this.valueKey]
);
this.$emit("input", value);
console.log(this.selectedTable.dataSource);
this.$emit("commitData", this.selectedTable.dataSource);
this.close();
},
/** 删除已选择的 */
handleDeleteSelected(record, index) {
this.selectionRows.splice(
this.selectedRowKeys.indexOf(record[this.rowKey]),
1
);
this.selectedRowKeys.splice(
this.selectedRowKeys.indexOf(record[this.rowKey]),
1
);
this.selectedTable.dataSource.splice(index, 1);
console.log(this.selectedRowKeys, this.selectionRows);
},
customRowFn(record) {
return {
on: {
click: () => {
let key = record[this.rowKey];
if (!this.multiple) {
this.selectedRowKeys = [key];
this.selectedTable.dataSource = [record];
} else {
let index = this.selectedRowKeys.indexOf(key);
if (index === -1) {
this.selectedRowKeys.push(key);
this.selectedTable.dataSource.push(record);
} else {
this.handleDeleteSelected(record, index);
}
}
},
},
};
},
},
};
</script>
<style lang="less" scoped>
</style>
这边的方法通单选框是一样的
5.关于没有封装的单选框表格同时要实现点击行增加单选框选中效果
<a-table
style="width: 100%; margin-top: 50px"
:rowKey="(record) => record.id"
:dataSource="tableData"
:columns="columns"
:row-selection="{
type: 'radio',
onChange: onSelectChange,
selectedRowKeys: selectedRowKeys,
}"
:customRow="customRowFn"
@change="handleTableChange"
:pagination="ipagination"
:loading="tableLoading"
bordered
>
</a-table>
data(){
return{
tableSelectRow: {},
selectedRowKeys: [],
/* 分页参数 */
ipagination: {
current: 1,
pageSize: 10,
total: 0,
},
}
}
method:{
//控制单选框
onSelectChange(val, row) {
console.log("val", val, "row", row);
this.tableSelectRow = row[0];
this.selectedRowKeys = val;
},
//控制行customRowFn属性
customRowFn(record) {
return {
on: {
click: () => {
// console.log("record", record);
this.tableSelectRow = record;
this.selectedRowKeys = [record.id];
// console.log("this.tableSelectRow", this.tableSelectRow);
// console.log("this.selectedRowKeys", this.selectedRowKeys);
},
},
};
},
handleTableChange(pagination) {
//分页、排序、筛选变化时触发
this.ipagination = pagination;
this.getlistassetstandardmodel();
},
}
// 资产型号确定
chosmodelok() {
console.log(this.assetsData);
console.log(this.tableSelectRow);
this.form.setFieldsValue({
assetName: this.tableSelectRow.standardName,
categoryId: this.tableSelectRow.categoryId,
assetModel: this.tableSelectRow.standardModel,
assetMetering: this.tableSelectRow.standardMetering,
});
(this.assetsData.categoryName = this.tableSelectRow.categoryName),
(this.chosmodel = false);
},
6.关于没有封装的单选框表格同时要实现点击行增加多选框选中效果
<a-table
:columns="columns"
:data-source="dataSource"
size="small"
rowKey="id"
:loading="loading"
:pagination="ipagination"
bordered
:rowSelection="{
selectedRowKeys: selectedRowKeys,
onChange: onChangeTableSelect,
}"
:customRow="customRowFn"
@change="handleTableChange"
>
selectedRowKeys: [],
selectionRows: [],
methods: {
customRowFn(record) {
return {
on: {
click: () => {
// console.log("record", record);
// this.tableSelectRow = record;
// this.selectedRowKeys = [record.id];
// console.log("this.tableSelectRow", this.tableSelectRow);
// console.log("this.selectedRowKeys", this.selectedRowKeys);
let key = record.id;
let index = this.selectedRowKeys.indexOf(key);
// console.log("index", index);
if (index === -1) {
this.selectedRowKeys.push(key);
this.selectionRows.push(record);
} else {
this.selectionRows.splice(
this.selectionRows.indexOf(record.id),
1
);
this.selectedRowKeys.splice(
this.selectedRowKeys.indexOf(record.id),
1
);
}
console.log("this.selectionRows", this.selectionRows);
},
},
};
},
onChangeTableSelect(selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys;
let mRow = JSON.parse(JSON.stringify(this.selectionRows));
selectionRows.forEach((item) => {
pushIfNotExist(mRow, item, "id");
});
this.selectionRows = this.selectedRowKeys.map((item) => {
let mObj = {};
mRow.forEach((items) => {
if (items.id == item) {
mObj = items;
}
});
console.log(mObj);
return mObj;
});
console.log(this.selectionRows);
},
clickShowModal(rows) {
let mRows = JSON.parse(JSON.stringify(rows));
this.onClearSelected();
this.selectedRowKeys = mRows.map((item) => item.id);
this.selectionRows = mRows;
this.visible = true;
this.loadData(1);
},
handleOk() {
this.visible = false;
this.$emit(
"select",
JSON.parse(JSON.stringify(this.selectedRowKeys)),
JSON.parse(JSON.stringify(this.selectionRows))
);
},
},
};
这边表格分页效果是来自JeecgListMixin这个组件或者看5那边有单独写出来分页
/**
* 新增修改完成调用 modalFormOk方法 编辑弹框组件ref定义为modalForm
* 高级查询按钮调用 superQuery方法 高级查询组件ref定义为superQueryModal
* data中url定义 list为查询列表 delete为删除单条记录 deleteBatch为批量删除
*/
import { filterObj } from "@/utils/util";
import { deleteAction, getAction, downFile, getFileAccessHttpUrl } from "@/api/manage";
export const JeecgListMixin = {
data() {
return {
/* 查询条件-请不要在queryParam中声明非字符串值的属性 */
queryParam: {},
/* 数据源 */
dataSource: [],
/* 分页参数 */
ipagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ["10", "20", "30"],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " 共" + total + "条";
},
showQuickJumper: true,
showSizeChanger: true,
total: 0,
},
/* 排序参数 */
isorter: {
column: "createTime",
order: "desc",
},
/* 筛选参数 */
filters: {},
/* table加载状态 */
loading: false,
/* table选中keys*/
selectedRowKeys: [],
/* table选中records*/
selectionRows: [],
/* 查询折叠 */
toggleSearchStatus: false,
/* 高级查询条件生效状态 */
superQueryFlag: false,
/* 高级查询条件 */
superQueryParams: "",
/** 高级查询拼接方式 */
superQueryMatchType: "and",
};
},
created() {
if (!this.disableMixinCreated) {
console.log(" -- mixin created -- ");
this.loadData();
//初始化字典配置 在自己页面定义
this.initDictConfig();
}
},
computed: {},
methods: {
loadData(arg) {
if (!this.url.list) {
this.$message.error("请设置url.list属性!");
return;
}
//加载数据 若传入参数1则加载第一页的内容
if (arg === 1) {
this.ipagination.current = 1;
}
var params = this.getQueryParams(); //查询条件
this.loading = true;
getAction(this.url.list, params)
.then((res) => {
if (res.ok) {
//update-begin---author:zhangyafei Date:20201118 for:适配不分页的数据列表------------
this.dataSource = res.data.records || res.data;
if (res.data.total) {
this.ipagination.total = res.data.total;
} else {
this.ipagination.total = 0;
}
//update-end---author:zhangyafei Date:20201118 for:适配不分页的数据列表------------
} else {
this.$message.warning(res.msg);
}
})
.finally(() => {
this.loading = false;
});
},
initDictConfig() {
console.log("--这是一个假的方法!");
},
handleSuperQuery(params, matchType) {
//高级查询方法
if (!params) {
this.superQueryParams = "";
this.superQueryFlag = false;
} else {
this.superQueryFlag = true;
this.superQueryParams = JSON.stringify(params);
this.superQueryMatchType = matchType;
}
this.loadData(1);
},
getQueryParams() {
//获取查询条件
let sqp = {};
if (this.superQueryParams) {
sqp["superQueryParams"] = encodeURI(this.superQueryParams);
sqp["superQueryMatchType"] = this.superQueryMatchType;
}
var param = Object.assign(sqp, this.queryParam, this.isorter, this.filters);
// param.field = this.getQueryField();
param.current = this.ipagination.current;
param.size = this.ipagination.pageSize;
return filterObj(param);
},
getQueryField() {
//TODO 字段权限控制
var str = "id,";
this.columns.forEach(function (value) {
str += "," + value.dataIndex;
});
return str;
},
onSelectChange(selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectionRows;
console.log(selectedRowKeys, selectionRows);
},
onClearSelected() {
this.selectedRowKeys = [];
this.selectionRows = [];
},
searchQuery() {
this.loadData(1);
},
superQuery() {
this.$refs.superQueryModal.show();
},
searchReset() {
this.queryParam = {};
this.loadData(1);
},
batchDel: function () {
if (!this.url.deleteBatch) {
this.$message.error("请设置url.deleteBatch属性!");
return;
}
if (this.selectedRowKeys.length <= 0) {
this.$message.warning("请选择一条记录!");
return;
} else {
var ids = "";
for (var a = 0; a < this.selectedRowKeys.length; a++) {
ids += this.selectedRowKeys[a] + ",";
}
var that = this;
this.$confirm({
title: "确认删除",
content: "是否删除选中数据?",
onOk: function () {
that.loading = true;
deleteAction(that.url.deleteBatch, { ids: ids })
.then((res) => {
if (res.success) {
//重新计算分页问题
that.reCalculatePage(that.selectedRowKeys.length);
that.$message.success(res.message);
that.loadData();
that.onClearSelected();
} else {
that.$message.warning(res.message);
}
})
.finally(() => {
that.loading = false;
});
},
});
}
},
handleDelete: function (id) {
if (!this.url.delete) {
this.$message.error("请设置url.delete属性!");
return;
}
var that = this;
deleteAction(`${that.url.delete}/${id}`, { id: id }).then((res) => {
if (res.ok) {
//重新计算分页问题
that.reCalculatePage(1);
that.$message.success("操作成功");
that.loadData();
} else {
that.$message.warning(res.msg);
}
});
},
reCalculatePage(count) {
//总数量-count
let total = this.ipagination.total - count;
//获取删除后的分页数
let currentIndex = Math.ceil(total / this.ipagination.pageSize);
//删除后的分页数<所在当前页
if (currentIndex < this.ipagination.current) {
this.ipagination.current = currentIndex;
}
console.log("currentIndex", currentIndex);
},
handleEdit: function (record) {
this.$refs.modalForm.edit(record);
this.$refs.modalForm.title = "编辑";
this.$refs.modalForm.disableSubmit = false;
},
handleAdd: function () {
this.$refs.modalForm.add();
this.$refs.modalForm.title = "新增";
this.$refs.modalForm.disableSubmit = false;
},
handleTableChange(pagination, filters, sorter) {
//分页、排序、筛选变化时触发
//TODO 筛选
console.log(pagination);
if (Object.keys(sorter).length > 0) {
// this.isorter.column = sorter.field;
this.isorter.order = "ascend" == sorter.order ? "asc" : "desc";
}
this.ipagination = pagination;
this.loadData();
},
handleToggleSearch() {
this.toggleSearchStatus = !this.toggleSearchStatus;
},
// 给popup查询使用(查询区域不支持回填多个字段,限制只返回一个字段)
getPopupField(fields) {
return fields.split(",")[0];
},
modalFormOk() {
// 新增/修改 成功时,重载列表
this.loadData();
//清空列表选中
this.onClearSelected();
},
handleDetail: function (record) {
this.$refs.modalForm.edit(record);
this.$refs.modalForm.title = "详情";
this.$refs.modalForm.disableSubmit = true;
},
/* 导出 */
handleExportXls2() {
let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
let url = `${window._CONFIG["domianURL"]}/${this.url.exportXlsUrl}?paramsStr=${paramsStr}`;
window.location.href = url;
},
handleExportXls(fileName) {
if (!fileName || typeof fileName != "string") {
fileName = "导出文件";
}
let param = this.getQueryParams();
if (this.selectedRowKeys && this.selectedRowKeys.length > 0) {
param["selections"] = this.selectedRowKeys.join(",");
}
console.log("导出参数", param);
downFile(this.url.exportXlsUrl, param).then((data) => {
if (!data) {
this.$message.warning("文件下载失败");
return;
}
if (typeof window.navigator.msSaveBlob !== "undefined") {
window.navigator.msSaveBlob(new Blob([data], { type: "application/vnd.ms-excel" }), fileName + ".xls");
} else {
console.log(data);
let url = window.URL.createObjectURL(new Blob([data.data], { type: "application/vnd.ms-excel" }));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
link.setAttribute("download", fileName + ".xls");
document.body.appendChild(link);
link.click();
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
}
});
},
/* 图片预览 */
getImgView(text) {
if (text && text.indexOf(",") > 0) {
text = text.substring(0, text.indexOf(","));
}
return getFileAccessHttpUrl(text);
},
/* 文件下载 */
// update--autor:lvdandan-----date:20200630------for:修改下载文件方法名uploadFile改为downloadFile------
downloadFile(text) {
if (!text) {
this.$message.warning("未知的文件");
return;
}
if (text.indexOf(",") > 0) {
text = text.substring(0, text.indexOf(","));
}
let url = getFileAccessHttpUrl(text);
window.open(url);
},
},
};
7.打印和导出写法
// 打印资产标签列表
const printAssetList = (fileName, params) => downloadFile("/asset/warehousing/printAssetList", fileName, params, "pdf"); // 打印资产标签列表
//导出资产列表
const warehousingExport = (fileName, params) => downloadFile("/asset/assetsinfo/export", fileName, params, "get"); // 导出资产列表
// 打印资产
clickAssetsPrint() {
this.assetsPrintLoading = true;
var mm = {};
mm.id = this.selectedRows.map((item) => {
return item.materialCode;
});
printAssetList("资产标签", mm)
.then((res) => {
this.assetsPrintLoading = false;
})
.catch((err) => {
this.assetsPrintLoading = false;
});
// this.$refs.barCode.transferData(this.selectedRows)
},
// 导出资产
getWarehousingExport() {
var mm = {};
mm.id = this.selectedRows.map((item) => {
return item.materialCode;
});
warehousingExport("资产列表", mm).then((res) => {
// let execlName = "资产文件名称";
// const buf = Buffer.from(res),
// blob = new Blob([buf], { type: "application/vnd.ms-excel" }),
// downloadElement = document.createElement('a'),
// href = window.URL.createObjectURL(blob); // 创建下载的链接
// downloadElement.href = href;
// downloadElement.download = `${execlName}.xls`; // 下载后文件名
// document.body.appendChild(downloadElement);
// downloadElement.click(); // 点击下载
// window.URL.revokeObjectURL(href); // 释放掉blob对象
});
},
8.显示已删除的供应商
<a-checkbox
style="margin-left: 20px"
@change="onChange"
:value="yesOfno"
>
显示已删除的供应商
</a-checkbox>
onChange(e) {
this.yesOfno = e.target.checked;
this.$refs.table.refresh(this.queryParam);
},
<s-table
ref="table"
size="default"
:columns="columns"
:data="loadData"
@onSelect="onChangeTableSelect"
>
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" />
<a-popconfirm title="你确定要删除吗?" @confirm="deleteTable(record)">
<a>删除</a>
</a-popconfirm>
</span>
</s-table>
refresh() {
var mm = {
current: 1,
total: 0,
size: this.pageSize,
}
this.loadData(mm);
},
同时也有关于loadData传参查询
// 加载数据方法 必须为 Promise 对象
loadData: (parameter) => {
this.queryParam.delFlag = this.yesOfno ? 1 : "";
return listSupplierinfo(Object.assign(parameter, this.queryParam)).then(
(res) => {
console.log(res);
var mm = { data: [] };
mm.size = res.data.size;
mm.current = res.data.current;
mm.totalCount = res.data.total;
mm.totalPage = res.data.pages;
mm.data = res.data.records;
return mm;
}
);
},
9.关于loadData传参查询
loadData: (parameter) => {
return allotapplyPage(Object.assign(parameter, this.queryParam)).then(
(res) => {
var mm = { data: [] };
mm.size = res.data.size;
mm.current = res.data.current;
mm.totalCount = res.data.total;
mm.totalPage = res.data.pages;
mm.data = res.data.records;
return mm;
}
);
},
10.关于mixins传参功能
@mixin fontStyle($size,$weight,$color){
font-size: $size;
font-weight: $weight;
color:$color;
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
}
使用
.num {
@include fontStyle(24px, bold, #1fc6ff);
}
11.关于批量操作的样式
<a-dropdown v-if="arrayId.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="deleteModel">
<a-icon type="delete" />删除
</a-menu-item>
<!-- lock | unlock -->
<!-- <a-menu-item key="2"><a-icon type="lock" />锁定</a-menu-item> -->
</a-menu>
<a-button style="margin-left: 8px">
批量操作
<a-icon type="down" />
</a-button>
</a-dropdown>
12.树形查找
如果当前的层级id没有找到就会执行执行他的子对象中寻找匹配的id。
该函数首先尝试在当前层级的项目中通过item.id == id
寻找匹配的id。如果当前层级没有匹配项,并且当前项目包含子项(即item.children
存在),它会递归地调用自身this.findLabelById(id, item.children)
去子对象中寻找匹配的id。这一过程会持续到找到匹配的id并返回其对应的标签,或者遍历完所有可能的子对象仍未找到匹配项时,最终返回null。
findLabelById(id, deption) {
for (const item of deption) {
if (item.id == id) {
return item.label;
}
if (item.children) {
const label = this.findLabelById(id, item.children);
if (label) {
return label;
}
}
}
return null; // 如果没有找到匹配的id,返回null
},
问题能否将这段代码改成else
if (item.children) {
const label = this.findLabelById(id, item.children);
if (label) {
return label;
}
}
不能如果改成else违背的最开始的逻辑 这是在没有顶级层的情况下去检查他的子项。
13.table里面带有输入框怎么写
<div v-if="houseType == '1'">
<a-table
bordered
ref="tableSelect"
size="default"
rowKey="id"
:columns="columns"
:data-source="dataSource"
>
<div slot="assetRentAreas" slot-scope="text, record, index">
<a-input-number
v-model="dataSource[index].assetRentAreas"
:min="0"
@change="changedataSource"
/>
</div>
<div slot="singlePrice" slot-scope="text, record, index">
<a-input-number
v-model="dataSource[index].singlePrice"
:min="0"
@change="changedataSource"
/>
</div>
<span slot="action" slot-scope="text, record, index">
<a @click="deleteRecord(record, index)" style="color: red"
>删除</a
>
</span></a-table
>
</div>
methods: {
// 计算 资产租金
changedataSource() {
if (this.houseType == 1) {
this.dataSource = this.dataSource.map((item) => {
return {
...item,
monthRentMoney:
item.assetRentAreas > 0 && item.singlePrice > 0
? (item.assetRentAreas * item.singlePrice).toFixed(2)
: 0,
yearRentMoney:
item.assetRentAreas > 0 && item.singlePrice > 0
? (item.assetRentAreas * item.singlePrice * 12).toFixed(2)
: 0,
};
});
} else {
this.dataSource = this.dataSource.map((item) => {
return {
...item,
monthRentMoney:
item.number > 0 && item.singlePrice > 0
? (item.number * item.singlePrice).toFixed(2)
: 0,
yearRentMoney:
item.number > 0 && item.singlePrice > 0
? (item.number * item.singlePrice * 12).toFixed(2)
: 0,
};
});
}
},
14.关于当有校验情况撑开布局,布局跳动情况
今天碰到了一种布局跳动的情况 我就放了一个row n个col 但是有校验的情况撑开了布局 有3种解决方式
第一种方法:假设一行2个 那么有5行 就放5个row,之前就一个row margin导致可以往下挤压。
第二种:找到对应的标签去掉margin
第三种:清除缓存。因为我电脑有问题,但是我同事电脑没问题。有可能是缓存的问题
15.碰到纯数字或者字母的时候比较长的时候会直接下一行
css中添加
word-break: break-all;
16.碰到mixins.scss传值写法
@mixin fontStyle($size,$weight,$color){
font-size: $size;
font-weight: $weight;
color:$color;
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
}
传值
@include fontStyle(12px, 400, rgba(255, 255, 255, 0.7));
17. v-decorator使用和校验
使用v-decorator就不能使用v-model了,而且她用于a-form-item
<a-form
:form="editForm"
:labelCol="{ span: 6 }"
:wrapperCol="{ span: 16 }"
>
<a-row>
<a-col :span="12">
<a-form-item label="小区名称:">
<a-input
placeholder="请输入"
v-decorator="[
'name',
{ rules: validatorRules.inputIf.rules },
]"
/>
</a-form-item>
</a-col>
</a-row>
</a-form>
表单验证规则
validatorRules: {
// 表单验证
inputIf: { rules: [{ required: true, message: "此项不能为空" }] },
timeIf: { rules: [{ required: true, message: "请选择时间" }] },
},
同时 这说明了这个form一点要创建
editForm: this.$form.createForm(this),
表单验证validateFields
handleOk() {
this.editForm.validateFields((err, values) => {
if (!err) {
this.summit(values);
}
});
},
summit(values) {
this.xqLoading = true;
values.longitude = this.formData.longitude;
values.latitude = this.formData.latitude;
values.linkLand = this.formData.linkLand;
values.landName = this.formData.landName;
if (this.isAdd) {
Adddistrict(Object.assign(values))
.then((res) => {
this.xqLoading = false;
if (res.code == 0) {
this.$message.success("添加成功");
this.$emit("refresh");
this.visible = false;
} else {
this.$message.error(res.data.msg);
}
})
.catch((err) => {
this.xqLoading = false;
});
} else {
values.id = this.key;
Updatedistrict(Object.assign(values))
.then((res) => {
this.xqLoading = false;
if (res.code == 0) {
this.$message.success("修改成功");
this.$emit("refresh");
this.visible = false;
} else {
this.$message.error(res.data.msg);
}
})
.catch((err) => {
this.xqLoading = false;
});
}
},
表单清空
this.editForm.resetFields();
动态设置输入框的值写法setFieldsValue
this.editForm.setFieldsValue({ ["location"]: e.address });
该函数用于在Vue实例中,设置editForm
对象中location
属性的值为e.address
。其中,setFieldsValue
是Ant Design Vue库中Form
组件的方法,用于设置表单域的值。通过使用索引语法["location"]
,可以动态地设置属性名。
18.v-html遇上富文本的时候就可以不用管html标签了
19.关于文件打开
<a-descriptions-item label="附件">
<div
v-for="(item, index) of fileList"
:key="index"
class="filename"
@click="perView(item)"
>
{{ item.name }}
</div>
</a-descriptions-item>
perView(item) {
window.open(item.url, "_blank");
},
20.文件上传组件
<template>
<div class="upload-file">
<a-upload
v-if="!isUpload"
name="file"
:multiple="true"
:action="uploadFileUrl"
:headers="headers"
@change="handleChange"
:fileList="fileList"
>
<!-- 上传按钮 -->
<a-button> <a-icon type="upload" />上传</a-button>
</a-upload>
<div
class="upload-file-list el-upload-list el-upload-list--text"
name="el-fade-in-linear"
v-else
>
<div
:key="file.url"
class="el-upload-list__item ele-upload-list__item-content"
style="padding: 0 4px"
v-for="(file, index) in fileList"
>
<a :href="`${file.url}`" :underline="false" target="_blank">
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
</a>
</div>
</div>
</div>
</template>
<script>
import Cookie from "js-cookie";
export default {
name: "FileUpload",
props: {
// 值
value: [String, Object, Array],
// 大小限制(MB)
fileSize: {
type: Number,
default: 5,
},
// 文件类型, 例如['png', 'jpg', 'jpeg']
fileType: {
type: Array | Boolean,
// default: () => ["doc", "xls", "ppt", "txt", "pdf"],
default: () => ["doc", "docx", "xls", "xlsx", "ppt", ".pptx", "pdf"],
},
// 是否显示文件列表
isFileList: {
type: Boolean,
default: true,
},
dataIndex: {
type: Number | String,
default: 0,
},
// 是否禁用
isUpload: {
type: Boolean,
default: false,
},
},
data() {
return {
number: 0,
uploadList: [],
baseUrl: process.env.VUE_APP_BASE_API,
uploadFileUrl: `${process.env.VUE_APP_API_FATHER_URL}/upms/file/upload?fileType=image&dir=material/`, // 上传文件服务器地址
headers: {
// 请求头部
Authorization: Cookie.get("Authorization"),
},
fileList: [],
};
},
watch: {
value: {
async handler(val) {
if (val) {
console.log(111111);
let temp = 1;
// 首先将值转为数组
let list = Array.isArray(val)
? val
: val.split(",").map((item) => {
const [url, name] = item.split(":");
return { url, name };
});
// 然后将数组转为对象数组
this.fileList = list.map((item) => {
item = {
name: item.name,
url: item.url,
status: "done",
};
item.uid = new Date().getTime() + temp++;
return item;
});
} else {
this.fileList = [];
return [];
}
},
deep: true,
immediate: true,
},
},
methods: {
getFilenameFromUrl(url) {
var match = url.match(/^.*\/(.*)$/);
return match ? match[1] : null;
},
// 上传前校检格式和大小
handleBeforeUpload(file) {
// 校检文件类型
if (this.fileType) {
const fileName = file.name.split(".");
const fileExt = fileName[fileName.length - 1];
const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
if (!isTypeOk) {
this.$message.info(
`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`
);
return false;
}
}
// 校检文件大小
if (this.fileSize) {
const isLt = file.size / 1024 / 1024 < this.fileSize;
if (!isLt) {
this.$message.info(`上传文件大小不能超过 ${this.fileSize} MB!`);
return false;
}
}
this.number++;
return true;
},
// 上传失败
handleUploadError(err) {
this.$message.info("上传文件失败,请重试");
},
// 上传成功回调
handleChange(info) {
if (info.file.status !== "uploading") {
console.log(info.file, info.fileList);
}
let fileList = [...info.fileList];
fileList = fileList.map((file) => {
if (file.response) {
file.name = file.name;
file.url = file.response.link;
}
return file;
});
this.fileList = fileList;
if (info.file.status === "removed") {
console.log("this.fileList1111", this.fileList);
this.$emit("getFile", this.fileList);
this.$emit("input", this.fileList);
this.$emit("change", this.fileList);
}
if (info.file.status === "done") {
// console.log(info.file);
// this.$emit("getFile", this.listToString(this.fileList));
this.$emit("getFile", this.fileList);
this.$emit("input", this.fileList);
this.$emit("change", this.fileList);
}
if (info.file.status === "error") {
this.$message.error(`${info.file.name} file upload failed.`);
}
},
// 获取文件名称
getFileName(name) {
// console.log("name", name);
// 如果是url那么取最后的名字 如果不是直接返回
if (name.lastIndexOf("/") > -1) {
return name.slice(name.lastIndexOf("/") + 1);
} else {
return name;
}
},
// 对象转成指定字符串分隔
listToString(list, separator) {
let strs = "";
separator = separator || ",";
for (let i in list) {
strs += list[i].url + separator;
}
return strs != "" ? strs.substr(0, strs.length - 1) : "";
},
},
};
</script>
<style scoped lang="scss">
.upload-file-uploader {
margin-bottom: 5px;
}
.upload-file-list .el-upload-list__item {
line-height: 2;
margin-bottom: 10px;
position: relative;
}
.upload-file-list .ele-upload-list__item-content {
display: flex;
justify-content: space-between;
align-items: center;
color: inherit;
}
.ele-upload-list__item-content-action .el-link {
margin-right: 10px;
}
</style>
使用
<template>
<a-modal
:title="title"
width="30%"
:visible="visible"
@cancel="visible = false"
@ok="handleOk"
:loading="loading"
:footer="disabled ? null : undefined"
>
<a-form-model
ref="ruleForm"
:model="form"
:rules="rules"
:label-col="labelCol"
:wrapper-col="wrapperCol"
>
<a-form-model-item label="文档名称" prop="docName">
<a-input v-model="form.docName" :disabled="disabled" />
</a-form-model-item>
<a-form-model-item label="附件">
<FileUpload
v-model="form.fileIDS"
:fileType="false"
@getFile="getFile"
:disabled="disabled"
:isUpload="isUpload"
></FileUpload>
</a-form-model-item>
</a-form-model>
</a-modal>
</template>
<script>
import FileUpload from "@/components/FileUpload/index2";
import { maphelpcenterPost, maphelpcenterPut } from "@/api/myapi";
import { JeecgListMixin } from "@/mixins/JeecgListMixin";
export default {
components: { FileUpload, JeecgListMixin },
data() {
return {
loading: false,
visible: false,
title: "",
spinning: false,
form: {},
rules: {
docName: [{ required: true, message: "请输入", trigger: "blur" }],
},
labelCol: {
span: 5,
},
wrapperCol: {
span: 16,
},
record: {},
disabled: false,
isUpload: false,
footer: "",
};
},
methods: {
clickShowModal(isadd, data, disabled) {
console.log("data", data);
this.visible = true;
this.disabled = disabled;
this.isUpload = false;
if (isadd) {
this.title = "添加文档";
this.form = {};
this.footer = "111";
} else {
if (disabled) {
this.title = "查看文档";
this.isUpload = true;
} else {
this.title = "编辑文档";
}
this.form = { ...data };
this.form.fileIDS = this.mergeFiles(data.fileUrls, data.fileNames);
console.log("this.form.fileIDS", this.form.fileIDS);
}
},
maphelpcenterPost() {
this.loading = true;
console.log("this.form", this.form);
maphelpcenterPost(this.form).then((res) => {
this.loading = false;
console.log("res", res);
if (res.code == 0) {
this.$message.success("添加成功");
this.visible = false;
this.$emit("searchQuery");
}
});
},
maphelpcenterPut() {
this.loading = true;
maphelpcenterPut(this.form).then((res) => {
this.loading = false;
if (res.code == 0) {
this.$message.success("修改成功");
this.visible = false;
this.$emit("searchQuery");
}
});
},
handleOk() {
this.$refs.ruleForm.validate((valid) => {
if (valid) {
if (!this.form.id) {
this.maphelpcenterPost();
} else {
this.maphelpcenterPut();
}
} else {
console.log("error submit!!");
return false;
}
});
},
getFile(data) {
console.log("我收到了值", data);
this.form.fileUrls = data.map((item) => item.url).join(",");
this.form.fileNames = data.map((item) => item.name).join(",");
this.form.fileIDS = data.map((item) => item.uid).join(",");
// console.log("this.form.fileUrls", this.form.fileUrls);
// console.log("this.form.fileNames", this.form.fileNames);
},
mergeFiles(url, names) {
const urlArray = url.split(",");
const nameArray = names.split(",");
// console.log("urlArray", urlArray);
// console.log("nameArray", nameArray);
const a = urlArray.map((item, index) => ({
url: item,
name: nameArray[index],
}));
return a;
},
},
};
</script>
21.这里使用了一个计算属性或插值表达式{{ [...] [item.type] }}
来映射item.type
的数值到具体的描述文本。
<tbody>
<tr v-for="(item, index) in todoList" :key="index">
<div @click="toAudit(item)" style="margin-bottom: 12px">
<td class="title">
<a-tag color="#23689a">
{{
[
"",
"固定性资产管理",
"经营性资产登记",
"经营性资产变更",
][item.type]
}}
</a-tag>
</td>
<td class="content">
<span>{{ item.title }} </span>
</td>
</div>
</tr>
</tbody>
22.需求是
可以考虑实际收款不等于应收时候触发强制重新校验remark字段,可以考虑自定义校验
<a-row :gutter="48">
<a-col :span="6">
<a-form-model-item label="实收款:">
<a-input
v-model="form.realReceiveMoney"
:disabled="disabled"
@change="handleRealReceiveMoneyChange"
/>
</a-form-model-item>
</a-col>
<a-col :span="6">
<a-form-model-item label="实收日期">
<a-date-picker
valueFormat="YYYY-MM-DD"
style="width: 100%"
v-model="form.realReceiveDate"
:disabled="disabled"
/>
</a-form-model-item>
</a-col>
<a-col :span="6">
<a-form-model-item label="备注" prop="remark">
<a-input v-model="form.remark" :disabled="disabled" />
</a-form-model-item>
</a-col>
<a-col :span="6">
<a-button
type="primary"
@click="assetbillpaylogtAdd"
v-if="!disabled"
>
确认已缴费
</a-button>
实际收款不等于应收时候触发强制重新校验remark字段
handleRealReceiveMoneyChange() {
this.$refs.ruleForm.validateField("remark");
},
validateRemark(rule, value, callback) {
if (this.form.realReceiveMoney != this.shouldPayMoney && !value) {
callback(new Error("请输入备注"));
} else {
callback();
}
},
//新增缴费
assetbillpaylogtAdd() {
this.confirmLoading = true;
const meta = {
...this.form,
billIds: this.form.id,
contractId: this.form.rentContractId,
};
console.log("meta", meta);
this.$refs.ruleForm.validate((valid) => {
if (valid) {
assetbillpaylogtAdd(meta).then((res) => {
this.confirmLoading = false;
if (res.code == 0) {
this.$message.success("缴费成功");
this.visible = false;
this.$emit("getBillDetail");
}
});
} else {
console.log("校验不通过");
}
});
},
23.单选的表格
<a-table
ref="table"
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:rowSelection="{
selectedRowKeys: selectedRowKeys,
onChange: onSelectChange,
type: 'radio',
}"
:pagination="false"
bordered
>
<span slot="action" slot-scope="text, record">
<a v-if="record.payStatus == 1" @click="payment(record, false)">缴费</a>
<a v-else @click="payment(record, true)">详情</a>
</span>
</a-table>
import { JeecgListMixin } from "@/mixins/JeecgListMixin";
onSelectChange(selectedRowKeys, selectionRows) {
// console.log("selectedRowKeys", selectedRowKeys);
// console.log("selectionRows", selectionRows);
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectionRows;
// this.selectedRowKeys = row;
this.billList(
this.selectionRows[0].id,
this.selectionRows[0].rentContractId
);
},
JeecgListMixin的代码
/**
* 新增修改完成调用 modalFormOk方法 编辑弹框组件ref定义为modalForm
* 高级查询按钮调用 superQuery方法 高级查询组件ref定义为superQueryModal
* data中url定义 list为查询列表 delete为删除单条记录 deleteBatch为批量删除
*/
import { filterObj } from "@/utils/util";
import { deleteAction, getAction, downFile, getFileAccessHttpUrl } from "@/api/manage";
export const JeecgListMixin = {
data() {
return {
/* 查询条件-请不要在queryParam中声明非字符串值的属性 */
queryParam: {},
/* 数据源 */
dataSource: [],
/* 分页参数 */
ipagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ["10", "20", "30"],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " 共" + total + "条";
},
showQuickJumper: true,
showSizeChanger: true,
total: 0,
},
/* 排序参数 */
isorter: {
column: "createTime",
order: "desc",
},
/* 筛选参数 */
filters: {},
/* table加载状态 */
loading: false,
/* table选中keys*/
selectedRowKeys: [],
/* table选中records*/
selectionRows: [],
/* 查询折叠 */
toggleSearchStatus: false,
/* 高级查询条件生效状态 */
superQueryFlag: false,
/* 高级查询条件 */
superQueryParams: "",
/** 高级查询拼接方式 */
superQueryMatchType: "and",
};
},
created() {
if (!this.disableMixinCreated) {
console.log(" -- mixin created -- ");
this.loadData();
//初始化字典配置 在自己页面定义
this.initDictConfig();
}
},
computed: {},
methods: {
loadData(arg) {
if (!this.url.list) {
this.$message.error("请设置url.list属性!");
return;
}
//加载数据 若传入参数1则加载第一页的内容
if (arg === 1) {
this.ipagination.current = 1;
}
var params = this.getQueryParams(); //查询条件
this.loading = true;
getAction(this.url.list, params)
.then((res) => {
if (res.ok) {
console.log('res', res);
//update-begin---author:zhangyafei Date:20201118 for:适配不分页的数据列表------------
this.dataSource = res.data.records || res.data.list || res.data;
if (res.data.total) {
this.ipagination.total = res.data.total;
} else {
this.ipagination.total = 0;
}
//update-end---author:zhangyafei Date:20201118 for:适配不分页的数据列表------------
} else {
this.$message.warning(res.msg);
}
})
.finally(() => {
this.loading = false;
});
},
initDictConfig() {
console.log("--这是一个假的方法!");
},
handleSuperQuery(params, matchType) {
//高级查询方法
if (!params) {
this.superQueryParams = "";
this.superQueryFlag = false;
} else {
this.superQueryFlag = true;
this.superQueryParams = JSON.stringify(params);
this.superQueryMatchType = matchType;
}
this.loadData(1);
},
getQueryParams() {
//获取查询条件
let sqp = {};
if (this.superQueryParams) {
sqp["superQueryParams"] = encodeURI(this.superQueryParams);
sqp["superQueryMatchType"] = this.superQueryMatchType;
}
var param = Object.assign(sqp, this.queryParam, this.isorter, this.filters);
// param.field = this.getQueryField();
param.current = this.ipagination.current;
param.size = this.ipagination.pageSize;
return filterObj(param);
},
getQueryField() {
//TODO 字段权限控制
var str = "id,";
this.columns.forEach(function (value) {
str += "," + value.dataIndex;
});
return str;
},
onSelectChange(selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectionRows;
console.log(selectedRowKeys, selectionRows);
},
onClearSelected() {
this.selectedRowKeys = [];
this.selectionRows = [];
},
searchQuery() {
this.loadData(1);
},
superQuery() {
this.$refs.superQueryModal.show();
},
searchReset() {
this.queryParam = {};
this.loadData(1);
},
batchDel: function () {
if (!this.url.deleteBatch) {
this.$message.error("请设置url.deleteBatch属性!");
return;
}
if (this.selectedRowKeys.length <= 0) {
this.$message.warning("请选择一条记录!");
return;
} else {
var ids = "";
for (var a = 0; a < this.selectedRowKeys.length; a++) {
ids += this.selectedRowKeys[a] + ",";
}
var that = this;
this.$confirm({
title: "确认删除",
content: "是否删除选中数据?",
onOk: function () {
that.loading = true;
deleteAction(that.url.deleteBatch, { ids: ids })
.then((res) => {
if (res.success) {
//重新计算分页问题
that.reCalculatePage(that.selectedRowKeys.length);
that.$message.success(res.message);
that.loadData();
that.onClearSelected();
} else {
that.$message.warning(res.message);
}
})
.finally(() => {
that.loading = false;
});
},
});
}
},
handleDelete: function (id) {
if (!this.url.delete) {
this.$message.error("请设置url.delete属性!");
return;
}
var that = this;
deleteAction(`${that.url.delete}/${id}`, { id: id }).then((res) => {
if (res.ok) {
//重新计算分页问题
that.reCalculatePage(1);
that.$message.success("操作成功");
that.loadData();
} else {
that.$message.warning(res.msg);
}
});
},
reCalculatePage(count) {
//总数量-count
let total = this.ipagination.total - count;
//获取删除后的分页数
let currentIndex = Math.ceil(total / this.ipagination.pageSize);
//删除后的分页数<所在当前页
if (currentIndex < this.ipagination.current) {
this.ipagination.current = currentIndex;
}
console.log("currentIndex", currentIndex);
},
handleEdit: function (record) {
this.$refs.modalForm.edit(record);
this.$refs.modalForm.title = "编辑";
this.$refs.modalForm.disableSubmit = false;
},
handleAdd: function () {
this.$refs.modalForm.add();
this.$refs.modalForm.title = "新增";
this.$refs.modalForm.disableSubmit = false;
},
handleTableChange(pagination, filters, sorter) {
//分页、排序、筛选变化时触发
//TODO 筛选
console.log(pagination);
if (Object.keys(sorter).length > 0) {
// this.isorter.column = sorter.field;
this.isorter.order = "ascend" == sorter.order ? "asc" : "desc";
}
this.ipagination = pagination;
this.loadData();
},
handleToggleSearch() {
this.toggleSearchStatus = !this.toggleSearchStatus;
},
// 给popup查询使用(查询区域不支持回填多个字段,限制只返回一个字段)
getPopupField(fields) {
return fields.split(",")[0];
},
modalFormOk() {
// 新增/修改 成功时,重载列表
this.loadData();
//清空列表选中
this.onClearSelected();
},
handleDetail: function (record) {
this.$refs.modalForm.edit(record);
this.$refs.modalForm.title = "详情";
this.$refs.modalForm.disableSubmit = true;
},
/* 导出 */
handleExportXls2() {
let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
let url = `${window._CONFIG["domianURL"]}/${this.url.exportXlsUrl}?paramsStr=${paramsStr}`;
window.location.href = url;
},
handleExportXls(fileName) {
if (!fileName || typeof fileName != "string") {
fileName = "导出文件";
}
let param = this.getQueryParams();
if (this.selectedRowKeys && this.selectedRowKeys.length > 0) {
param["selections"] = this.selectedRowKeys.join(",");
}
console.log("导出参数", param);
downFile(this.url.exportXlsUrl, param).then((data) => {
if (!data) {
this.$message.warning("文件下载失败");
return;
}
if (typeof window.navigator.msSaveBlob !== "undefined") {
window.navigator.msSaveBlob(new Blob([data], { type: "application/vnd.ms-excel" }), fileName + ".xls");
} else {
console.log(data);
let url = window.URL.createObjectURL(new Blob([data.data], { type: "application/vnd.ms-excel" }));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
link.setAttribute("download", fileName + ".xls");
document.body.appendChild(link);
link.click();
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
}
});
},
/* 图片预览 */
getImgView(text) {
if (text && text.indexOf(",") > 0) {
text = text.substring(0, text.indexOf(","));
}
return getFileAccessHttpUrl(text);
},
/* 文件下载 */
// update--autor:lvdandan-----date:20200630------for:修改下载文件方法名uploadFile改为downloadFile------
downloadFile(text) {
if (!text) {
this.$message.warning("未知的文件");
return;
}
if (text.indexOf(",") > 0) {
text = text.substring(0, text.indexOf(","));
}
let url = getFileAccessHttpUrl(text);
window.open(url);
},
toggleAdvanced() {
this.advanced = !this.advanced;
},
},
};
表格多选 这边handleTableChange是分页的 上边单选没有分页 如果需要就添加
<a-table
:columns="columns"
:data-source="dataSource"
size="small"
rowKey="id"
:loading="loading"
:pagination="ipagination"
bordered
:rowSelection="{
selectedRowKeys: selectedRowKeys,
onChange: onChangeTableSelect,
}"
@change="handleTableChange"
>
</a-table>
import { JeecgListMixin } from "@/mixins/JeecgListMixin";
onChangeTableSelect(selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys;
let mRow = JSON.parse(JSON.stringify(this.selectionRows));
selectionRows.forEach((item) => {
pushIfNotExist(mRow, item, "id");
});
this.selectionRows = this.selectedRowKeys.map((item) => {
let mObj = {};
mRow.forEach((items) => {
if (items.id == item) {
mObj = items;
}
});
return mObj;
});
console.log("11111", this.selectionRows);
},