养老补贴

master
lion 1 week ago
parent a938853688
commit 3156b6a86e

@ -0,0 +1,29 @@
import request from '@/utils/request'
export function index(params, isLoading = true) {
return request({
method: 'get',
url: '/api/admin/old-age-allowance/index',
params,
isLoading
})
}
export function show(params, isLoading = true) {
return request({
method: 'get',
url: '/api/admin/old-age-allowance/show',
params,
isLoading
})
}
export function destroy(params, isLoading = true) {
return request({
method: 'get',
url: '/api/admin/old-age-allowance/destroy',
params,
isLoading
})
}

@ -48,11 +48,29 @@ export async function download(url, method = "get", info, filename) {
loading.close();
// 提取文件名
// 提取文件名(兼容 Content-Disposition: filename / filename*
if (!filename) {
filename =
response.headers["content-disposition"]?.match(/filename=(.*)/)[1] ||
const cd =
response.headers["content-disposition"] ||
response.headers["Content-Disposition"] ||
"";
let fromHeader = "";
if (cd) {
const star = cd.match(/filename\*=(?:UTF-8'')?([^;\n]+)/i);
const plain = cd.match(/filename[^*]=["']?([^";\n]+)["']?/i);
fromHeader = (star && star[1]) || (plain && plain[1]) || "";
if (fromHeader.includes("%")) {
try {
fromHeader = decodeURIComponent(fromHeader.trim());
} catch (e) {
fromHeader = fromHeader.trim();
}
}
}
filename = fromHeader || "导出.xlsx";
if (!/\.(xlsx|xls|csv)$/i.test(filename)) {
filename += ".xlsx";
}
}
// 将二进制流转为blob
@ -61,7 +79,7 @@ export async function download(url, method = "get", info, filename) {
});
if (typeof window.navigator.msSaveBlob !== "undefined") {
// 兼容IEwindow.navigator.msSaveBlob以本地方式保存文件
window.navigator.msSaveBlob(blob, decodeURI(filename));
window.navigator.msSaveBlob(blob, filename);
} else {
// 创建新的URL并指向File对象或者Blob对象的地址
const blobURL = window.URL.createObjectURL(blob);
@ -69,7 +87,7 @@ export async function download(url, method = "get", info, filename) {
const tempLink = document.createElement("a");
tempLink.style.display = "none";
tempLink.href = blobURL;
tempLink.setAttribute("download", decodeURI(filename));
tempLink.setAttribute("download", filename);
// 兼容某些浏览器不支持HTML5的download属性
if (typeof tempLink.download === "undefined") {
tempLink.setAttribute("target", "_blank");

@ -0,0 +1,275 @@
<template>
<div>
<el-card shadow="never" style="margin-top: 20px;">
<template #header>
<vxe-toolbar :print="isHasAuth('print')" custom ref="toolbar">
<template #toolSuffix>
<vxe-button
v-if="isHasAuth('export')"
style="margin-right: 10px;"
icon="vxe-icon-download"
circle
@click="exportMethod"
/>
</template>
<!-- <template #buttons>
<el-button v-if="isHasAuth('search')" icon="el-icon-search" type="primary" plain size="small" @click="handleSearch">
搜索
</el-button>
</template> -->
</vxe-toolbar>
</template>
<el-form :inline="true" class="search-bar" @submit.native.prevent="handleSearch">
<el-form-item label="手机号">
<el-input
v-model="searchForm.mobile"
clearable
placeholder="模糊查询"
style="width: 220px"
/>
</el-form-item>
<el-form-item label="内容">
<el-input
v-model="searchForm.content"
clearable
placeholder="模糊查询"
style="width: 280px"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="handleSearch"></el-button>
<el-button size="small" @click="handleReset"></el-button>
</el-form-item>
</el-form>
<vxe-table
ref="table"
stripe
style="margin-top: 10px"
:loading="loading"
:height="tableHeight"
show-overflow
:export-config="{}"
:row-config="{ isCurrent: true, isHover: true }"
:column-config="{ resizable: true }"
:align="allAlign"
:data="tableData"
>
<vxe-column type="seq" width="58" align="center" />
<vxe-column align="center" field="mobile" width="180" title="手机号" />
<vxe-column align="center" field="content" min-width="340" title="提交内容" />
<vxe-column align="center" field="created_at" width="180" title="提交时间" />
<vxe-column field="operate" header-align="center" title="操作" width="180" fixed="right">
<template #default="{ row }">
<el-button v-if="isHasAuth('detail')" size="small" type="primary" plain @click="detail(row)"></el-button>
<el-button v-if="isHasAuth('delete')" size="small" type="danger" @click="destroyRowEvent(row)"></el-button>
</template>
</vxe-column>
</vxe-table>
<el-pagination
style="margin-top: 10px;display: flex;justify-content: flex-end;"
:current-page.sync="select.page"
:page-sizes="[20, 30, 40, 50]"
:page-size.sync="select.page_size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="onPageSizeChange"
@current-change="onCurrentChange"
/>
</el-card>
<el-dialog title="养老补贴提交详情" :visible.sync="isShowDetail" width="600px">
<el-descriptions :column="1" border size="small">
<el-descriptions-item label="手机号">{{ detailForm.mobile || '-' }}</el-descriptions-item>
<el-descriptions-item label="提交内容">{{ detailForm.content || '-' }}</el-descriptions-item>
<el-descriptions-item label="提交时间">{{ detailForm.created_at || '-' }}</el-descriptions-item>
</el-descriptions>
</el-dialog>
</div>
</template>
<script>
import { authMixin } from '@/mixin/authMixin'
import { download } from '@/utils/downloadRequest'
import { destroy, index, show } from '@/api/old-age-allowance/old-age-allowance'
export default {
name: 'OldAgeAllowance',
mixins: [authMixin],
data() {
return {
isShowDetail: false,
loading: false,
tableHeight: 400,
searchForm: {
mobile: '',
content: ''
},
select: {
page: 1,
page_size: 20,
show_relation: []
},
total: 0,
allAlign: null,
tableData: [],
detailForm: {}
}
},
computed: {
isHasAuth() {
return function(auth) {
return this.auths_auth_mixin.indexOf(auth) !== -1
}
}
},
created() {
this.getList()
},
mounted() {
this.bindToolbar()
this.calcTableHeight()
},
methods: {
buildFilter() {
const filter = []
const mobile = (this.searchForm.mobile || '').trim()
const content = (this.searchForm.content || '').trim()
if (mobile) {
filter.push({ key: 'mobile', op: 'like', value: mobile })
}
if (content) {
filter.push({ key: 'content', op: 'like', value: content })
}
return filter
},
/**
* 与项目中通用列表接口一致filter **JSON 字符串**单参数
* 避免 axios 将数组序列成 filter[]=<JSON> 导致后端无法解析
* @see BaseController::normalizeIndexFilter
*/
getListParams(extra = {}) {
const params = {
page: this.select.page,
page_size: this.select.page_size,
...extra
}
const filter = this.buildFilter()
if (filter.length) {
params.filter = JSON.stringify(filter)
}
return params
},
getExportParams() {
const params = this.getListParams({
page: 1,
page_size: 9999,
is_export: 1,
file_name: '养老补贴提交记录.xlsx'
})
params.export_fields = JSON.stringify({
mobile: '手机号',
content: '提交内容',
created_at: '提交时间'
})
return params
},
handleSearch() {
this.select.page = 1
this.getList()
},
handleReset() {
this.searchForm.mobile = ''
this.searchForm.content = ''
this.select.page = 1
this.getList()
},
exportMethod() {
this.$confirm('请选择导出方式', '提示', {
confirmButtonText: '全量导出',
cancelButtonText: '部分导出',
distinguishCancelAndClose: true
}).then(() => {
download(
'/api/admin/old-age-allowance/index',
'get',
this.getExportParams(),
'养老补贴提交记录.xlsx'
)
}).catch((action) => {
if (action === 'cancel' && this.$refs.table) {
this.$refs.table.openExport()
}
})
},
calcTableHeight() {
const clientHeight = document.documentElement.clientHeight
const cardTitle = document.querySelector('.el-card__header')?.getBoundingClientRect()?.height
const search = document.querySelector('.vxe-toolbar')?.getBoundingClientRect()?.height
const paginationHeight = (document.querySelector('.el-pagination')?.getBoundingClientRect()?.height ?? 0) + 10
const topHeight = 50
const padding = 80
const margin = 20
this.tableHeight = clientHeight - cardTitle - search - paginationHeight - topHeight - padding - margin
},
bindToolbar() {
this.$nextTick(() => {
if (this.$refs.table && this.$refs.toolbar) {
this.$refs.table.connect(this.$refs.toolbar)
}
})
},
async getList() {
this.loading = true
try {
const res = await index(this.getListParams(), false)
this.tableData = res.data
this.total = res.total
} finally {
this.loading = false
}
},
async detail(row) {
const res = await show({ id: row.id }, false)
this.detailForm = res || {}
this.isShowDetail = true
},
async destroyRowEvent(row) {
await this.$confirm('确认删除?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消'
})
this.loading = true
try {
await destroy({ id: row.id }, false)
await this.getList()
} finally {
this.loading = false
}
},
onPageSizeChange(size) {
this.select.page_size = size
this.select.page = 1
this.getList()
},
onCurrentChange(page) {
this.select.page = page
this.getList()
}
}
}
</script>
<style scoped lang="scss">
::v-deep .el-card__header {
padding: 6px 20px;
}
.search-bar {
margin-bottom: 6px;
padding: 0 4px 4px;
}
</style>

@ -25,7 +25,7 @@ module.exports = {
* Detail: https://cli.vuejs.org/config/#publicpath
*/
publicPath: process.env.ENV === 'staging' ? '/admin_test' : '/admin',
outputDir: `/Users/mac/Documents/朗业/2024/y-四世同堂-医康养/yikangyang/public${process.env.ENV === 'staging' ? '/admin_test' : '/admin'}`,
outputDir: `../yikangyang/public${process.env.ENV === 'staging' ? '/admin_test' : '/admin'}`,
assetsDir: 'static',
css: {
loaderOptions: { // 向 CSS 相关的 loader 传递选项

Loading…
Cancel
Save