From 06f22f5674670016808457dbddd1065a180b9fcd Mon Sep 17 00:00:00 2001 From: SjS <email@example.com> Date: Tue, 8 Apr 2025 16:04:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8B=9B=E5=95=86=E5=8A=A0=E7=9B=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/bst/mchApply.js | 57 ++ src/utils/constants.js | 5 + .../components/SimpleVerifyDialog.vue | 105 ++++ src/views/bst/mchApply/index.vue | 486 ++++++++++++++++++ src/views/system/user/UserLink.vue | 35 ++ 5 files changed, 688 insertions(+) create mode 100644 src/api/bst/mchApply.js create mode 100644 src/views/bst/mchApply/components/SimpleVerifyDialog.vue create mode 100644 src/views/bst/mchApply/index.vue create mode 100644 src/views/system/user/UserLink.vue diff --git a/src/api/bst/mchApply.js b/src/api/bst/mchApply.js new file mode 100644 index 0000000..95cddcd --- /dev/null +++ b/src/api/bst/mchApply.js @@ -0,0 +1,57 @@ +import request from '@/utils/request' + +// 查询招商加盟列表 +export function listMchApply(query) { + return request({ + url: '/bst/mchApply/list', + method: 'get', + params: query + }) +} + +// 查询招商加盟详细 +export function getMchApply(applyId) { + return request({ + url: '/bst/mchApply/' + applyId, + method: 'get' + }) +} + +// 新增招商加盟 +export function addMchApply(data) { + return request({ + url: '/bst/mchApply', + method: 'post', + data: data + }) +} + +// 修改招商加盟 +export function updateMchApply(data) { + return request({ + url: '/bst/mchApply', + method: 'put', + data: data + }) +} + +// 删除招商加盟 +export function delMchApply(applyId) { + return request({ + url: '/bst/mchApply/' + applyId, + method: 'delete' + }) +} + +// 审核商家合作申请 +export function verifyMchApply(applyId, pass, remark) { + return request({ + url: `/bst/mchApply/${applyId}/verify`, + method: 'put', + params: { + applyId, + pass, + remark + } + }) +} diff --git a/src/utils/constants.js b/src/utils/constants.js index ad04934..a1e6d59 100644 --- a/src/utils/constants.js +++ b/src/utils/constants.js @@ -4,6 +4,11 @@ import { getLastDate, getLastDateTimeEnd, getLastDateTimeStart, getLastMonth, ge export const views = { } +export const UserType = { + ADMIN: "1", // 管理员 + APP: "2" // 普通用户 +} + // 日期选择器快捷选项 export const DatePickerOptions = { // 默认 diff --git a/src/views/bst/mchApply/components/SimpleVerifyDialog.vue b/src/views/bst/mchApply/components/SimpleVerifyDialog.vue new file mode 100644 index 0000000..371732c --- /dev/null +++ b/src/views/bst/mchApply/components/SimpleVerifyDialog.vue @@ -0,0 +1,105 @@ +<template> + <el-dialog :title="title" :visible="show" width="500px" center @open="open" @close="close"> + <el-form :model="form" :rules="rules" ref="form"> + <el-form-item label="审核意见" prop="remark"> + <el-input + type="textarea" + maxlength="200" + show-word-limit + v-model="form.remark" + placeholder="请输入审核意见,该审核意见会反馈给申请用户" + :rows="5" + /> + </el-form-item> + </el-form> + + <template #footer> + <el-button type="success" icon="el-icon-check" plain @click="handlePass">通过</el-button> + <el-button type="danger" icon="el-icon-close" plain @click="handleReject">驳回</el-button> + </template> + </el-dialog> +</template> + +<script> +export default { + name: 'SimpleVerifyDialog', + props: { + title: { + type: String, + default: '审核', + }, + show: { + type: Boolean, + default: false, + }, + requiredRemark: { + type: Boolean, + default: true, + }, + reset: { + type: Boolean, + default: true, + } + }, + data() { + return { + form: {}, + rules: { + remark: [ + {required: this.requiredRemark, message: '审核意见不能为空', trigger: 'blur'} + ] + } + } + }, + created() { + this.resetForm(); + }, + methods: { + open() { + if (this.reset) { + this.resetForm(); + } + }, + close() { + this.$emit('update:show', false); + }, + resetForm() { + this.form = { + remark: null, + } + }, + handleReject() { + this.$refs.form.validate((valid) => { + if (!valid) { + return; + } + this.$confirm('确认驳回吗?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }).then(() => { + this.$emit('reject', this.form); + }); + }); + }, + handlePass() { + this.$refs.form.validate((valid) => { + if (!valid) { + return; + } + this.$confirm('确认通过吗?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }).then(() => { + this.$emit('pass', this.form); + }); + }) + }, + } +} +</script> + +<style scoped lang="scss"> + +</style> diff --git a/src/views/bst/mchApply/index.vue b/src/views/bst/mchApply/index.vue new file mode 100644 index 0000000..601aaa6 --- /dev/null +++ b/src/views/bst/mchApply/index.vue @@ -0,0 +1,486 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> + <el-form-item label="用户名称" prop="userId"> + <el-input + v-model="queryParams.userName" + placeholder="请输入用户名称" + clearable + @change="handleQuery" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="姓名" prop="name"> + <el-input + v-model="queryParams.name" + placeholder="请输入姓名" + clearable + @change="handleQuery" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="手机号" prop="mobile"> + <el-input + v-model="queryParams.mobile" + placeholder="请输入手机号" + clearable + @change="handleQuery" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="申请状态" prop="status"> + <el-select v-model="queryParams.status" clearable @change="handleQuery" placeholder="请选择申请状态"> + <el-option + v-for="dict in dict.type.mch_apply_status" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + <el-form-item label="审核人" prop="verifyName"> + <el-input + v-model="queryParams.verifyName" + placeholder="请输入审核人名称" + clearable + @change="handleQuery" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button + type="danger" + plain + icon="el-icon-delete" + size="mini" + :disabled="multiple" + @click="handleDelete" + v-hasPermi="['bst:mchApply:remove']" + >删除</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="warning" + plain + icon="el-icon-download" + size="mini" + @click="handleExport" + v-hasPermi="['bst:mchApply:export']" + >导出</el-button> + </el-col> + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> + </el-row> + + <el-table v-loading="loading" :data="mchApplyList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="ID" align="center" prop="applyId" width="50"/> + <el-table-column label="用户名称" align="center" prop="userName" > + <template slot-scope="scope"> + <span>{{ scope.row.userName }}</span> + </template> + </el-table-column> + <el-table-column label="姓名" align="center" prop="name" /> + <el-table-column label="手机号" align="center" prop="mobile" /> + <el-table-column label="创建时间" align="center" prop="createTime" width="180"/> + <el-table-column label="申请状态" align="center" prop="status"> + <dict-tag slot-scope="d" :value="d.row.status" :options="dict.type.mch_apply_status"/> + </el-table-column> + <el-table-column label="审核人" align="center" prop="verifyName" /> + <el-table-column label="审核时间" align="center" prop="verifyTime" width="180"/> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + icon="el-icon-view" + @click="handleView(scope.row)" + v-hasPermi="['bst:mchApply:remove']" + >查看详情</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total>0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + + + <!-- 在index.vue的template中添加弹窗结构 --> + <el-dialog + :title="`商户申请详情`" + :visible.sync="detailVisible" + width="800px" + append-to-body> + + <!-- 申请信息区块 --> + <div class="info-section"> + <el-descriptions title="申请信息" :column="2" border> + <el-descriptions-item label="申请用户">{{ detailForm.userName }}</el-descriptions-item> + <el-descriptions-item label="申请时间">{{ detailForm.createTime }}</el-descriptions-item> + <el-descriptions-item label="申请状态"> + <dict-tag :value="detailForm.status" :options="dict.type.mch_apply_status"/> + </el-descriptions-item> + <el-descriptions-item label="姓名">{{ detailForm.name }}</el-descriptions-item> + <el-descriptions-item label="手机号">{{ detailForm.mobile }}</el-descriptions-item> + <el-descriptions-item label="设备情况"> + <el-tag :type="detailForm.hasDevice ? 'success' : 'danger'" size="small"> + {{ detailForm.hasDevice ? '已有设备' : '暂无设备' }} + </el-tag> + </el-descriptions-item> + <el-descriptions-item label="经营模式"> + <dict-tag :value="detailForm.operateMode" :options="dict.type.apply_operate_mode"/> + </el-descriptions-item> + <el-descriptions-item label="使用场景"> + {{ detailForm.scenes }} + </el-descriptions-item> + <!-- 合并后的详细信息 --> + <el-descriptions-item label="详细信息" :span="2"> + <pre class="content-pre">{{ detailForm.content }}</pre> + </el-descriptions-item> + </el-descriptions> + </div> + + <!-- 审核区块 --> + <el-divider v-if="isApproving" /> + <div v-if="isApproving" class="verify-area"> + <el-input + v-model="verifyRemark" + type="textarea" + :rows="4" + placeholder="请输入审核意见" + style="margin:20px 0" + :disabled="!isApproving" + /> + <div class="dialog-footer" style="display: flex; justify-content: flex-end; gap: 10px;"> + <el-button + type="danger" + @click="handleReject" + v-hasPermi="['bst:mchApply:verify']" + >驳 回</el-button> + <el-button + type="success" + @click="handleApprove" + v-hasPermi="['bst:mchApply:verify']" + >通 过</el-button> +<!-- <el-button @click="detailVisible = false">关闭</el-button>--> + </div> + + </div> + + <!-- 修改已审核信息展示结构 --> + <template v-if="!isApproving"> + <el-descriptions title="审核信息" :column="1" border style="margin-top:20px"> + <el-descriptions-item label="审核人" class="text-wrap">{{ detailForm.verifyName }}</el-descriptions-item> + <el-descriptions-item label="审核时间" class="text-wrap">{{ detailForm.verifyTime }}</el-descriptions-item> + <el-descriptions-item label="审核意见" class="text-wrap"> + <pre style="white-space: pre-wrap;">{{ detailForm.verifyRemark }}</pre> + </el-descriptions-item> + </el-descriptions> + <div class="dialog-footer" style="margin-top:20px"> + <el-button @click="detailVisible = false">关 闭</el-button> + </div> + </template> + </el-dialog> + + <!-- 添加或修改商家合作申请对话框 --> + <el-dialog :title="title" :visible.sync="open" width="650px" append-to-body> + <el-form ref="form" :model="form" :rules="rules" label-width="100px"> + <!-- 经营模式 --> + <el-form-item label="经营模式" prop="operateMode"> + <el-select + v-model="form.operateMode" + placeholder="请选择经营模式" + clearable + style="width: 100%" + > + <el-option + v-for="dict in dict.type.apply_operate_mode" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + + <!-- 是否有设备 --> + <el-form-item label="是否有设备" prop="hasDevice"> + <el-radio-group v-model="form.hasDevice"> + <el-radio :label="1">有设备</el-radio> + <el-radio :label="0">无设备</el-radio> + </el-radio-group> + </el-form-item> + + <!-- 使用场景 --> + <el-form-item label="使用场景" prop="scenes"> + <el-input + v-model="form.scenes" + placeholder="请输入使用场景" + type="textarea" + :rows="3" + /> + </el-form-item> + + <!-- 详细信息 --> + <el-form-item label="详细信息" prop="content"> + <el-input + v-model="form.content" + type="textarea" + :rows="5" + placeholder="请输入详细信息" + show-word-limit + maxlength="500" + /> + </el-form-item> + </el-form> + + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm">确 定</el-button> + <el-button @click="cancel">取 消</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { listMchApply, getMchApply, delMchApply, addMchApply, updateMchApply ,verifyMchApply} from "@/api/bst/mchApply"; + +export default { + name: "MchApply", + components: {}, + dicts: ['mch_apply_status',"apply_operate_mode"], + data() { + return { + // 遮罩层 + loading: true, + // 选中数组 + ids: [], + // 非单个禁用 + single: true, + // 非多个禁用 + multiple: true, + // 显示搜索条件 + showSearch: true, + // 总条数 + total: 0, + // 商家合作申请表格数据 + mchApplyList: [], + // 弹出层标题 + title: "", + // 是否显示弹出层 + open: false, + // 需要补充以下字段 + detailVisible: false, // 控制详情弹窗显示 + detailForm: {}, // 详情数据存储 + verifyRemark: '', // 审核意见输入 + // 查询参数 + queryParams: { + pageNum: 1, + pageSize: 20, + userId: null, + status: null, + name: null, + mobile: null, + content: null, + callback: null, + verifyName: null, + verifyTime: null, + verifyRemark: null, + }, + // 表单参数 + form: {}, + // 表单校验 + rules: { + userId: [ + { required: true, message: "用户id不能为空", trigger: "blur" } + ], + status: [ + { required: true, message: "申请状态不能为空", trigger: "change" } + ], + name: [ + { required: true, message: "姓名不能为空", trigger: "blur" } + ], + mobile: [ + { required: true, message: "手机号不能为空", trigger: "blur" } + ], + content: [ + { required: true, message: "详细信息不能为空", trigger: "blur" } + ], + createTime: [ + { required: true, message: "创建时间不能为空", trigger: "blur" } + ], + } + }; + }, + created() { + this.queryParams = { + ...this.queryParams, + ...this.$route.query + } + this.getList(); + }, + computed: { + isApproving() { + return this.detailForm.status === '1' //审核中状态 + }, + isView() { + return this.title === '查看商家合作申请'; + } + }, + methods: { + // 审核通过 + handleApprove() { + if (!this.verifyRemark) { + this.$message.warning('请填写审核意见') + return + } + this.$modal.confirm('确认通过该申请?').then(() => { + verifyMchApply(this.detailForm.applyId, true, this.verifyRemark) + .then(() => { + this.$message.success('审核通过') + this.detailVisible = false + this.getList() // 刷新列表 + }) + }) + }, + + // 审核驳回 + handleReject() { + if (!this.verifyRemark) { + this.$message.warning('请填写审核意见') + return + } + this.$modal.confirm('确认驳回该申请?').then(() => { + verifyMchApply(this.detailForm.applyId, false, this.verifyRemark) + .then(() => { + this.$message.success('已驳回') + this.detailVisible = false + this.getList() // 刷新列表 + }) + }) + }, + /** 查询商家合作申请列表 */ + getList() { + this.loading = true; + listMchApply(this.queryParams).then(response => { + this.mchApplyList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 取消按钮 + cancel() { + this.open = false; + this.reset(); + }, + // 表单重置 + reset() { + this.form = { + applyId: null, + userId: null, + status: null, + name: null, + mobile: null, + content: null, + remark: null, + callback: null, + verifyBy: null, + verifyTime: null, + verifyRemark: null, + createTime: null, + updateTime: null, + deleted: null + }; + this.resetForm("form"); + }, + /** 搜索按钮操作 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 重置按钮操作 */ + resetQuery() { + this.resetForm("queryForm"); + this.handleQuery(); + }, + // 多选框选中数据 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.applyId) + this.single = selection.length!==1 + this.multiple = !selection.length + }, + /** 新增按钮操作 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "合作申请"; + }, + /** 修改按钮操作 */ + handleUpdate(row) { + this.reset(); + const applyId = row.applyId || this.ids + getMchApply(applyId).then(response => { + this.form = response.data; + this.open = true; + this.title = "修改商家合作申请"; + }); + }, + handleView(row) { + this.loading = true; + getMchApply(row.applyId).then(response => { + this.detailForm = response.data; + this.detailVisible = true; + this.verifyRemark = ''; + }).finally(() => { + this.loading = false; + }); + }, + /** 提交按钮 */ + submitForm() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.applyId != null) { + updateMchApply(this.form).then(response => { + this.$modal.msgSuccess("修改成功"); + this.open = false; + this.getList(); + }); + } else { + addMchApply(this.form).then(response => { + this.$modal.msgSuccess("新增成功"); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 删除按钮操作 */ + handleDelete(row) { + const applyIds = row.applyId || this.ids; + this.$modal.confirm('是否确认删除商家合作申请编号为"' + applyIds + '"的数据项?').then(function() { + return delMchApply(applyIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("删除成功"); + }).catch(() => {}); + }, + /** 导出按钮操作 */ + handleExport() { + this.download('ss/mchApply/export', { + ...this.queryParams + }, `mchApply_${new Date().getTime()}.xlsx`) + } + } +}; +</script> diff --git a/src/views/system/user/UserLink.vue b/src/views/system/user/UserLink.vue new file mode 100644 index 0000000..ef8bc48 --- /dev/null +++ b/src/views/system/user/UserLink.vue @@ -0,0 +1,35 @@ +<template> + <el-link v-if="userType === UserType.ADMIN" type="primary" @click="handleClick" :disabled="id == null">{{name | defaultValue}}</el-link> + <span v-else >{{name | defaultValue}}</span> +</template> + +<script> +import { mapGetters } from 'vuex' +import { UserType } from '@/utils/constants' + +export default { + name: 'UserLink', + props: { + id: { + type: String, + default: null + }, + name: { + type: String, + default: null, + } + }, + computed: { + UserType() { + return UserType + }, + ...mapGetters(['userType']) + }, + methods: { + handleClick() { + this.$emit('click'); + this.$router.push({path: `/smUser/user/${this.id}`}) + } + } +} +</script>