You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

395 lines
14 KiB

<template>
<div>
<!-- 查询配置 -->
<div>
<div ref="lxHeader">
<LxHeader icon="md-apps" :text="title || customForm.tableName" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
<div slot="content" />
<slot>
<header-content :auths="auths_auth_mixin">
<template #search>
<div style="display: flex">
<Select v-model="select.filter[0].key" style="width: 100px;" placeholder="搜索条目">
<Option v-for="item in form" :key="item.id" :value="item.field">{{ item.name }}</Option>
</Select>
<Select v-model="select.filter[0].op" style="width: 100px;margin-left: 10px;" placeholder="搜索条件">
<Option v-for="item in op" :key="item.value" :value="item.value">{{ item.label }}</Option>
</Select>
<template v-if="select.filter[0].op !== 'range' && !columnArrTest(select.filter[0].key)">
<Input v-model="select.filter[0].value" style="width: 150px;margin-left: 10px;" placeholder="请填写关键词" />
</template>
<template v-else-if="select.filter[0].op !== 'range' && columnArrTest(select.filter[0].key)">
<Select v-model="select.filter[0].value" style="width: 150px;margin-left: 10px;" placeholder="请选择关键词">
<Option v-for="item in getColumnParams(select.filter[0].key)" :key="item.id" :value="item.id">{{ item.value || item.name || item.no || item.id }}</Option>
</Select>
</template>
<template v-else>
<Input
:value="select.filter[0].value.split(',')[0]"
style="width: 150px;margin-left: 10px;"
placeholder="范围开始关键词"
@input="(e)=>inputStartHandler(e,select.filter[0])"
/>
<span style="margin-left: 10px;display: flex;align-items: center;">至</span>
<Input
:value="select.filter[0].value.split(',')[1]"
style="width: 150px;margin-left: 10px;"
placeholder="范围结束关键词"
@input="(e)=>inputEndHandler(e,select.filter[0])"
/>
</template>
<Button
style="margin-left: 10px"
type="primary"
@click="$refs['xyTable'].getTableData(true)"
>查询</Button>
<xy-selectors
style="margin-left: 10px"
@reset="reset"
@search="$refs['xyTable'].getTableData(true)"
>
<template>
<div class="select">
<div v-for="(item,index) in select.filter" :key="`${item.value}-${index}`" class="select__item">
<p>条件{{ index+1 }}</p>
<Select v-model="item.key" style="width: 100px;" placeholder="搜索条目">
<Option v-for="item in form" :key="item.id" :value="item.field">{{ item.name }}</Option>
</Select>
<Select v-model="item.op" style="width: 100px;margin-left: 10px;" placeholder="搜索条件">
<Option v-for="item in op" :key="item.value" :value="item.value">{{ item.label }}</Option>
</Select>
<template v-if="item.op !== 'range' && !columnArrTest(item.key)">
<Input v-model="item.value" style="width: 150px;margin-left: 10px;" placeholder="请填写关键词" />
</template>
<template v-else-if="item.op !== 'range' && columnArrTest(item.key)">
<Select v-model="item.value" style="width: 150px;margin-left: 10px;" placeholder="请选择关键词">
<Option v-for="item in getColumnParams(item.key)" :key="item.id" :value="item.id">{{ item.value || item.name || item.no || item.id }}</Option>
</Select>
</template>
<template v-else>
<Input
:value="item.value.split(',')[0]"
style="width: 150px;margin-left: 10px;"
placeholder="范围开始关键词"
@input="(e)=>inputStartHandler(e,item)"
/>
<span style="margin-left: 10px;">至</span>
<Input
:value="item.value.split(',')[1]"
style="width: 150px;margin-left: 10px;"
placeholder="范围结束关键词"
@input="(e)=>inputEndHandler(e,item)"
/>
</template>
<el-button v-if="index !== 0" size="small" type="danger" icon="el-icon-delete" circle style="margin-left: 10px;" @click="select.filter.splice(index,1)" />
</div>
</div>
<div class="add-btn">
<el-button size="small" type="primary" icon="el-icon-plus" circle @click="select.filter.push({key: '',op: '',value: ''})" />
<span>新增一条</span>
</div>
</template>
</xy-selectors>
</div>
</template>
<template #create>
<Button
type="primary"
@click="$refs['dialog'].setType('add'),$refs['dialog'].show()"
>新增</Button>
</template>
<template #import>
<Button
type="primary"
@click="$refs['imports'].show()"
>导入</Button>
</template>
<template #export>
<Button
type="primary"
@click="exportExcel(new Date().getTime().toString())"
>导出</Button>
</template>
</header-content>
</slot>
</LxHeader>
</div>
</div>
<xy-table
ref="xyTable"
:auths="auths_auth_mixin"
:delay-req="true"
:destroy-action="destroy"
:border="true"
:action="index"
:req-opt="Object.assign(select,selectForm)"
:destroy-req-opt="select"
:table-item="table"
@detail="row => {
$refs['drawer'].setId(row.id);
$refs['drawer'].show();
}"
@editor="row => {
$refs['dialog'].setId(row.id);
$refs['dialog'].setType('editor');
$refs['dialog'].show();
}"
/>
<dialoger ref="dialog" :table-name="customForm.tableName" :form-info="form" @refresh="$refs['xyTable'].getTableData()" />
<drawer ref="drawer" :table-name="customForm.tableName" :form-info="form" />
<imports ref="imports" :table-name="customForm.tableName" :form-info="form" @refresh="$refs['xyTable'].getTableData()" />
</div>
</template>
<script>
import { index as fieldIndex } from '@/api/system/customFormField'
import { authMixin } from '@/mixin/authMixin'
import { index, destroy } from '@/api/system/baseForm'
import { op } from '@/const/op'
import { download } from '@/utils/downloadRequest'
import { getparameter } from '@/api/system/dictionary'
import { show } from '@/api/system/customForm'
import * as XLSX from 'xlsx'
import { saveAs } from 'file-saver'
import dialoger from './dialog.vue'
import LxHeader from '@/components/LxHeader/index.vue'
import headerContent from '@/components/LxHeader/XyContent.vue'
import drawer from '@/views/component/drawer.vue'
import imports from './imports.vue'
export default {
components: {
LxHeader,
dialoger,
headerContent,
drawer,
imports
},
mixins: [authMixin],
data() {
return {
title: '',
op,
select: {
table_name: '',
filter: [
{
key: '',
op: '',
value: ''
}
]
},
selectForm: [],
form: [],
table: [],
customForm: {
customFormId: '',
tableName: ''
}
}
},
computed: {
columnArrTest() {
return function(field) {
return this.form.find(i => i.field === field) ? this.form.find(i => i.field === field).search_input === 'checkbox' : false
}
},
getColumnParams() {
return function(field) {
return this.form.find(i => i.field === field) ? this.form.find(i => i.field === field)._paramters : []
}
}
},
created() {
this.getField()
this.getFormDetail()
},
methods: {
index, destroy, download,
reset() {
this.select.filter.splice(1)
this.select.filter[0] = {
key: '',
op: '',
value: ''
}
},
async exportExcel(sheetName) {
const res = await index(Object.assign(this.select, { page: 1, page_size: 9999 }))
if (res.data) {
const headers = this.form.map(i => {
return {
key: i.field,
title: i.name
}
})
const data = res.data.map(row => headers.map(header => row[header.key]))
data.unshift(headers.map(header => header.title))
const wb = XLSX.utils.book_new()
const ws = XLSX.utils.aoa_to_sheet(data)
XLSX.utils.book_append_sheet(wb, ws, sheetName)
const wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' })
saveAs(new Blob([wbout], { type: 'application/octet-stream' }), `${sheetName}.xlsx`)
}
},
// target要为内存地址引用类型
inputStartHandler(e, target) {
const temp = target?.value.split(',')[1]
target.value = `${e},${temp || ''}`
},
inputEndHandler(e, target) {
const temp = target?.value.split(',')[0]
target.value = `${temp || ''},${e}`
},
async getFormDetail() {
const res = await show({ id: this.customForm.customFormId }, false)
this.title = res.name
},
async getField() {
if (this.$route.meta.params?.custom_form) {
const decode = decodeURIComponent(this.$route.meta.params?.custom_form)
try {
const custom_form = JSON.parse(decode)
this.customForm.customFormId = custom_form.custom_form_id
this.customForm.tableName = custom_form.table_name
this.select.table_name = custom_form.table_name
} catch (err) {
console.warn(err)
}
}
const res = await fieldIndex({
page: 1,
page_size: 999,
custom_form_id: this.customForm.customFormId,
sort_name: 'sort',
sort_type: 'asc'
})
if (res.data && res.data instanceof Array) {
res.data.forEach(i => {
if (i.field) {
if (
(i.edit_input === 'checkbox' || i.edit_input === 'radio' || i.edit_input === 'select') &&
i.parameter_id
) {
getparameter({ id: i.parameter_id }).then((res) => {
i._paramters = res.detail ?? []
})
}
if (
(i.edit_input === 'checkbox' || i.edit_input === 'radio' || i.edit_input === 'select') &&
i.link_table_name
) {
index({
page: 1,
page_size: 999,
table_name: i.link_table_name
}).then((res) => {
i._paramters = res.data ?? []
})
}
}
})
}
this.form = res.data
this.selectForm = ''
this.table = res.data.map(i => {
const linkOb = {}
if (i.parameter_id) {
linkOb.customFn = row => {
return (
<span>{ row[i.link_with_name]?.value }</span>
)
}
}
if (i.link_table_name) {
if (i.link_relation === 'hasOne') {
linkOb.customFn = row => {
if (i.edit_input === 'file') {
return (
<a download={row[i.link_with_name]?.original_name} href={ row[i.link_with_name]?.url }>{ row[i.link_with_name]?.original_name }</a>
)
} else {
return (
<span>{ row[i.link_with_name]?.name || row[i.link_with_name]?.no || row[i.link_with_name]?.value }</span>
)
}
}
}
if (i.link_relation === 'hasMany') {
linkOb.customFn = row => {
return (
<div>
{ row[i.link_with_name]?.map(o => (<span>{ o?.name || o?.no || o?.value }</span>)) }
</div>
)
}
}
}
return Object.assign({
prop: i.field,
label: i.name,
width: i.width,
fixed: i.is_fixed
}, linkOb)
})
this.table.unshift({
type: 'index',
width: 60,
label: '序号',
fixed: 'left'
})
}
}
}
</script>
<style scoped lang="scss">
.select {
&__item {
& > p {
display: inline-block;
width: 80px;
text-align: center;
}
& + div {
margin-top: 6px;
}
}
}
.add-btn {
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
& > span {
padding: 0 10px;
}
}
a {
color: red;
text-decoration: none;
transition: all 0.2s;
}
a:hover {
color: red;
text-decoration: underline;
}
</style>