Commit 79d7d5e9 authored by caimeng's avatar caimeng

贷后资料下载页面完成

parent cf3d00a1
......@@ -10,6 +10,7 @@
"dependencies": {
"ali-oss": "^6.20.0",
"axios": "^0.21.1",
"dayjs": "^1.11.13",
"element-ui": "^2.15.13",
"express": "^4.17.1",
"file-saver": "^2.0.0",
......@@ -4790,6 +4791,11 @@
"node": "*"
}
},
"node_modules/dayjs": {
"version": "1.11.13",
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
},
"node_modules/de-indent": {
"version": "1.0.2",
"resolved": "https://registry.npm.taobao.org/de-indent/download/de-indent-1.0.2.tgz",
......@@ -17124,6 +17130,11 @@
"resolved": "https://registry.npmmirror.com/dateformat/-/dateformat-2.2.0.tgz",
"integrity": "sha512-GODcnWq3YGoTnygPfi02ygEiRxqUxpJwuRHjdhJYuxpcZmDq4rjBiXYmbCCzStxo176ixfLT6i4NPwQooRySnw=="
},
"dayjs": {
"version": "1.11.13",
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
},
"de-indent": {
"version": "1.0.2",
"resolved": "https://registry.npm.taobao.org/de-indent/download/de-indent-1.0.2.tgz",
......
......@@ -14,6 +14,7 @@
"dependencies": {
"ali-oss": "^6.20.0",
"axios": "^0.21.1",
"dayjs": "^1.11.13",
"element-ui": "^2.15.13",
"express": "^4.17.1",
"file-saver": "^2.0.0",
......
<template>
<div>
</div>
</template>
<script>
export default {
}
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
<template>
<el-form-item :label="label ? `${label}:` : ''" :prop="prop">
<component size="small" :is="`el-${component}`" v-model="currentValue" v-bind="options" v-on="$attrs.on">
<template v-if="component === 'select'">
<el-option
v-for="(item, index) in $attrs.options"
:key="index"
:label="item.label"
:value="item.value"
></el-option>
</template>
</component>
</el-form-item>
</template>
<script>
const defaultOptionMap = {
input: {
placeholder: label => `请输入${label}`,
},
select: {
placeholder: label => `请选择${label}`,
},
'date-picker': {
placeholder: label => `请选择${label}`,
valueFormat: 'yyyy-MM-dd',
},
'date-picker-daterange': {
valueFormat: 'yyyy-MM-dd',
rangeSeparator: '至',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
}
export default {
name: 'BaseFormItem',
inheritAttrs: false,
props: {
value: null,
label: String,
prop: {
type: String,
required: true,
},
component: {
type: String,
required: true,
},
},
computed: {
currentValue: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
},
},
options() {
const options = { ...this.$attrs }
const defaultOption = this.getDefaultOption()
return {
...defaultOption,
clearable: true,
...options,
}
},
},
methods: {
getDefaultOption() {
const { type } = this.$attrs
const key = type ? `${this.component}-${type}` : this.component
const defaultOption = defaultOptionMap[key] || defaultOptionMap[this.component] || {}
let placeholder = defaultOption.placeholder
if (placeholder) {
placeholder = typeof placeholder === 'function' ? placeholder(this.label) : placeholder
}
return { ...defaultOption, placeholder }
},
},
}
</script>
\ No newline at end of file
<template>
<div class="m-search">
<el-form ref="searchForm" v-model="values" inline @submit.native.prevent>
<SearchItem v-for="(item,index) in config" v-bind="item" v-model="values[item.prop]" :key="index" />
<slot name="footer">
<el-button icon="el-icon-plus" type="primary" size="small" @click="submit">搜索</el-button>
<el-button icon="el-icon-refresh-right" type="default" size="small" @click="reset">重置</el-button>
</slot>
</el-form>
</div>
</template>
<script>
import SearchItem from './form-item.vue'
export default {
name: "McSearch",
inheritAttrs: false,
components: {
SearchItem
},
props: {
value: null,
config: {
type: Array,
require: true,
default: () => []
},
onSubmit: Function,
onInput: Function
},
computed: {
values: {
get() {
return this.value || {}
},
set(val) {
this.onInput && this.onInput(val)
this.$emit('input', val)
}
}
},
watch: {
config: {
handler: 'initValues',
immediate: true,
deep: true
}
},
methods: {
initValues() {
this.values = this.config.reduce((values, item) => {
values[item.prop] = item.value
return values
}, {})
},
submit() {
const values = this.values;
this.onSubmit && this.onSubmit(values)
this.$emit('submit', values)
},
reset() {
this.$emit('reset')
this.$refs.searchForm.resetFields()
this.initValues()
this.submit()
}
},
}
</script>
<style lang="less" scoped>
.m-search{
.el-button{
margin-top: 4px;
}
}
</style>
\ No newline at end of file
export default {
name: 'ColumnRender',
functional: true,
props: {
scope: Object,
render: Function,
},
render: (h, ctx) => {
const { scope, render } = ctx.props
const { column, row, $index } = scope
return render ? render(h, row[column.property], row, $index) : ''
},
}
<template>
<el-table-column v-bind="column">
<!-- 默认插槽 -->
<template v-if="column.render" #default="scope">
<ColumnRender :scope="scope" :render="column.render" />
</template>
</el-table-column>
</template>
<script>
import ColumnRender from './column-render'
export default {
name: 'BaseColumn',
components: {
ColumnRender,
},
props: {
column: {
type: Object,
default: () => ({}),
},
},
}
</script>
<template>
<div class="common-table">
<slot name="Header"></slot>
<el-table
ref="multipleTable"
v-loading="loading"
:data="data"
v-bind="$attrs"
class="mb20"
border
v-on="$listeners"
@selection-change="handleSelectionChange"
@cell-click="tabClick"
>
<template v-for="column in finalColumns">
<el-table-column v-if="$scopedSlots[column.prop]" v-bind="column" :key="column.prop">
<template #default="scope">
<slot :name="column.prop" v-bind="scope"></slot>
</template>
</el-table-column>
<BaseColumn :key="column.prop" v-else :column="column" />
</template>
</el-table>
<BasePagination :pagination="pagination" @change="handleChange" />
</div>
</template>
<script>
import BaseColumn from './column'
import BasePagination from './pagination'
const defaultColumnOption = {
align: 'left',
showOverflowTooltip: true,
}
export default {
name: 'BaseTable',
components: {
BaseColumn,
BasePagination,
},
inheritAttrs: false,
props: {
data: Array,
columns: Array,
onChange: Function,
columnOptions: Object,
loading: {
type: Boolean,
default: false,
},
pagination: {
type: [Object, Boolean],
default: () => ({}),
},
},
computed: {
finalColumns() {
const { columnOptions, columns } = this
return columns.map(column => ({
...defaultColumnOption,
...columnOptions,
...column,
}))
},
},
methods: {
handleChange(pagination) {
if (this.onChange) {
this.onChange(pagination)
}
this.$emit('change', pagination)
},
handleSelectionChange(val) {
this.$emit('selectChange', val)
},
tabClick(row, column, cell) {
this.$emit('tabClick', row, column, cell)
},
clearSelection() {
this.$refs.multipleTable.clearSelection()
},
},
}
</script>
<style lang="less" scoped>
.common-table {
.mb20 {
margin-bottom: 20px;
}
}
</style>
<template>
<div v-if="pagination" class="common-pagination" :class="[`common-pagination--${position}`]">
<el-pagination
background
v-bind="options"
@size-change="handleChange($event, 'size')"
@current-change="handleChange($event, 'page')"
></el-pagination>
</div>
</template>
<script>
const defaultOption = {
total: 0,
currentPage: 1,
pageSize: 10,
pageSizes: [10, 20, 30, 40, 50],
layout: 'prev,pager,next,sizes,total,jumper',
}
export default {
name: 'BasePagination',
props: {
pagination: {
type: [Object, Boolean],
default: () => ({}),
},
},
computed: {
position() {
return this.pagination.position || 'right'
},
options() {
return {
...defaultOption,
...this.pagination,
currentPage: this.pagination.pageNo || this.pagination.currentPage,
}
},
},
methods: {
handleChange(val, action) {
let { currentPage: pageNo, pageSize } = this.options
if (action === 'page') {
pageNo = val
}
if (action === 'size') {
pageNo = 1
pageSize = val
}
this.$emit('change', { pageNo, pageSize })
},
},
}
</script>
<style lang="less" scoped>
.common-pagination {
display: flex;
&--left {
justify-content: flex-start;
}
&--center {
justify-content: center;
}
&--right {
justify-content: flex-end;
}
}
</style>
......@@ -43,8 +43,6 @@
<!-- 列表 -->
<div v-show="isShow">
<block-header title="客户列表"/>
<mc-table :data="list"></mc-table>
<el-table
border
size="small"
......
This diff is collapsed.
import BaseSearch from '@/components/McSearch/index.vue'
import BaseTable from '@/components/McTable/index.vue'
export function FormTableMixin(service, defaultProps = {}) {
const pagination = defaultProps && {
pageNo: 1,
pageSize: 10,
total: 0,
...defaultProps,
}
return {
components: {
BaseSearch,
BaseTable,
},
data() {
return {
form: {
value: null,
onSubmit: () => {
this.table.pagination.pageNo = 1
this.getList()
},
onInput: val => {
this.form.value = val
},
},
table: {
data: [],
pagination,
loading: false,
onChange: pagination => {
Object.assign(this.table.pagination, pagination)
this.getList()
},
},
}
},
mounted() {
// let parent = this.$options.parent
// // 定位到第一个 keep-alive 父组件
// while (parent && parent.$options._componentTag !== 'keep-alive') {
// parent = parent.$parent
// }
// if (!parent) {
// this.getList()
// }
// this.getList()
},
activated() {
// 由于 keep-alive 组件的缓存机制,这里需要在 activated 生命周期中
console.log('activated');
this.getList()
},
computed: {
params() {
const { pagination } = this.table
return {
...this.form.value,
pageNum: pagination.pageNo,
pageSize: pagination.pageSize,
}
},
},
methods: {
async getList() {
this.table.loading = true
try {
const { data = [], total = 0 } = (await service?.call(this, this.params, this)) || {}
this.table.loading = false
this.table.data = data
if (this.table.pagination) {
this.table.pagination.total = total * 1
}
} catch (error) {
console.error(error);
this.table.loading = false
}
},
},
}
}
......@@ -206,6 +206,15 @@ export default new Router({
filter: true
}
},
{
path: '/collection/download',
name: 'CollectionSearch',
component: resolve => require(['../views/collection/download.vue'], resolve),
meta: {
title: '法诉材料',
filter: true
}
},
]
},
......
import { GET, POST } from "@/utils/ajax";
// 初始化下载列表
export default {
GetCollectionDownLoad(data) {
return GET('/protocol/selectProtocolEnumList', data);
},
};
/**
* Created by jin.zhouhang on 17-7-19 上午10:01.
*/
import axios from 'axios'
import qs from 'qs'
import Cookies from 'js-cookie'
import axios from "axios";
import qs from "qs";
import Cookies from "js-cookie";
/** 测试环境 */
axios.defaults.baseURL = process.env.VUE_APP_API;
/* 所有ajax请求拦截 */
axios.interceptors.request.use(function(req) {
const token = Cookies.get('x-auth-token')
axios.interceptors.request.use(
function(req) {
const token = Cookies.get("x-auth-token");
if (token) {
req.headers['X-Auth-Token'] = token
// req.headers['token'] = localStorage.getItem("token_xxx")
req.headers["X-Auth-Token"] = token;
// req.headers['token'] = localStorage.getItem("token_xxx")
}
// 在发送请求之前做些什么
return req
}, function(error) {
return req;
},
function(error) {
// 对请求错误做些什么
return Promise.reject(error)
})
return Promise.reject(error);
}
);
/* 所有ajax响应拦截 */
axios.interceptors.response.use(
res => {
const token = res.headers['x-auth-token']
token && Cookies.set('x-auth-token', token)
(res) => {
const token = res.headers["x-auth-token"];
token && Cookies.set("x-auth-token", token);
if (res.status !== 200) {
throw new Error(res)
}
return res
},
error => {
return Promise.reject(error)
if (res.status !== 200) {
throw new Error(res);
}
)
return res;
},
(error) => {
return Promise.reject(error);
}
);
const Ajax = {
install(Vue) {
const $$get = (url, data) => {
if (data !== undefined) {
let b = true
for (const key in data) {
if (data[key] === null) {
continue
}
if (b) {
url += `?${key}=${data[key]}`
b = !b
} else {
url += `&${key}=${data[key]}`
}
}
}
export const GET = (url, data) => {
if (data !== undefined) {
let b = true;
for (const key in data) {
if (data[key] === null) {
continue;
}
if (b) {
url += `?${key}=${data[key]}`;
b = !b;
} else {
url += `&${key}=${data[key]}`;
}
}
}
return new Promise((resolve, reject) => {
axios.get(url)
.then(res => {
resolve(res)
})
.catch((err) => {
reject(err)
})
})
}
return new Promise((resolve, reject) => {
axios
.get(url)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
};
const $$post = (url, data) => {
return new Promise((resolve, reject) => {
axios.post(url, data)
.then(res => {
resolve(res)
})
.catch((err) => {
reject(err)
})
})
}
export const POST = (url, data) => {
return new Promise((resolve, reject) => {
axios
.post(url, data)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
};
const $$put = (url, data) => {
return new Promise((resolve, reject) => {
axios.put(url, data)
.then(res => {
resolve(res)
})
.catch((err) => {
reject(err)
})
})
}
const Ajax = {
install(Vue) {
const $$get = (url, data) => {
return GET(url, data);
};
const $$patch = (url, data) => {
return new Promise((resolve, reject) => {
axios.patch(url, qs.stringify(data))
.then(res => {
resolve(res)
})
.catch((err) => {
reject(err)
})
})
}
const $$post = (url, data) => {
return POST(url, data);
};
const $$put = (url, data) => {
return new Promise((resolve, reject) => {
axios
.put(url, data)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
};
const $$delete = (url, data) => {
if (data !== undefined) {
let b = true
for (const key in data) {
if (data[key] === null) {
continue
}
if (b) {
url += `?${key}=${data[key]}`
b = !b
} else {
url += `&${key}=${data[key]}`
}
}
}
const $$patch = (url, data) => {
return new Promise((resolve, reject) => {
axios
.patch(url, qs.stringify(data))
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
};
return new Promise((resolve, reject) => {
axios.delete(url)
.then(res => {
resolve(res)
})
.catch((err) => {
reject(err)
})
})
const $$delete = (url, data) => {
if (data !== undefined) {
let b = true;
for (const key in data) {
if (data[key] === null) {
continue;
}
if (b) {
url += `?${key}=${data[key]}`;
b = !b;
} else {
url += `&${key}=${data[key]}`;
}
}
}
Vue.prototype.$$ajax = axios
Vue.prototype.$$get = $$get
Vue.prototype.$$post = $$post
Vue.prototype.$$put = $$put
Vue.prototype.$$patch = $$patch
Vue.prototype.$$delete = $$delete
}
}
return new Promise((resolve, reject) => {
axios
.delete(url)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
};
Vue.prototype.$$ajax = axios;
Vue.prototype.$$get = $$get;
Vue.prototype.$$post = $$post;
Vue.prototype.$$put = $$put;
Vue.prototype.$$patch = $$patch;
Vue.prototype.$$delete = $$delete;
},
};
export default Ajax
\ No newline at end of file
export default Ajax;
......@@ -710,12 +710,12 @@ const enumUtils = {
/** 放款资方*/
enumOpts[21] = {
enumName: 'RiskLevelEnum', values: [
{value: '1', label: '解除等级'},
{value: '2', label: 'RP1-未到期低风险(预警)'},
{value: '3', label: 'R1-低风险(预警)'},
{value: '4', label: 'R2-中风险(警告)'},
{value: '5', label: 'R3-高风险(冻结)'},
{value: '6', label: 'R4-黑名单(禁止)'},
{value: 'R0', label: '解除等级'},
{value: 'RP1', label: 'RP1-未到期低风险(预警)'},
{value: 'R1', label: 'R1-低风险(预警)'},
{value: 'R2', label: 'R2-中风险(警告)'},
{value: 'R3', label: 'R3-高风险(冻结)'},
{value: 'R4', label: 'R4-黑名单(禁止)'},
]
};
......
<template>
<div class="page-download">
<block-header title="搜索" />
<BaseSearch v-bind="form" ref="search" :config="searchConfig"></BaseSearch>
<BaseTable v-bind="table" ref="table" :columns="columns"></BaseTable>
</div>
</template>
<script>
import _ from 'lodash'
import { FormTableMixin } from '@/mixins/form-table'
import dayjs from 'dayjs'
import API from '@/server/api'
// 获取列表
const service = async (params) => {
try{
const res = await API.GetCollectionDownLoad({...params})
console.log(res,'哈哈')
return {
data:'',
total:''
}
}catch{
console.log('报错了')
}
}
export default {
name: "CollectionDownload",
mixins: [FormTableMixin(service())],
data() {
return {
searchConfig: [
{
component: 'input',
prop: 'companyName',
label: '案件批次',
placeholder: '请输入案件批次'
},
{
component: 'select',
prop: 'b',
label: '状态',
placeholder: '请选择',
options: []
}
],
columns: [
{
label: '案件批次',
prop: 'companyName',
},
{
label: '案件数',
prop: 'a',
},
{
label: '状态',
prop: 'b',
},
{
label: '创建时间',
prop: 'c',
},
{
label: '更新时间',
prop: 'd',
},
{
label: '备注',
prop: 'e',
},
{
label: '操作人',
prop: 'f',
},
{
label: '创建时间',
prop: 'createdTime',
render: (_, text) => {
return <span>{text && dayjs(text).format('YYYY-MM-DD HH:mm:ss')}</span>
}
}
],
}
},
mounted() {
},
methods: {
async init() {
try {
const res = await this.$$get('/protocol/selectProtocolEnumList')
if (res.status === 200 && res.data.success) {
this.EnumList = res.data.result;
} else {
this.$message.error(res.data.message);
}
} catch (err) {
this.$message.error(res || '初始化协议枚举列表报错');
}
}
},
}
</script>
<style lang="less" scoped></style>
\ No newline at end of file
......@@ -2919,6 +2919,11 @@
"resolved" "https://registry.npmmirror.com/dateformat/-/dateformat-2.2.0.tgz"
"version" "2.2.0"
"dayjs@^1.11.13":
"integrity" "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
"resolved" "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz"
"version" "1.11.13"
"de-indent@^1.0.2":
"integrity" "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg=="
"resolved" "https://registry.npm.taobao.org/de-indent/download/de-indent-1.0.2.tgz"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment