Merge branch 'driver'

This commit is contained in:
xyc 2025-06-06 17:40:18 +08:00
commit 53aec3b076
18 changed files with 735 additions and 298 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 KiB

View File

@ -35,7 +35,7 @@ export default {
},
data() {
return {
title: '车联通后台管理系统',
title: '车联通管理系统',
logo: undefined,
}
}

View File

@ -138,6 +138,19 @@
<!--地址<el-input type="text" v-model="detailedAddress" style="width: 250px;" />-->
</el-form-item>
<el-form-item label="app_id" prop="appId">
<el-input v-model="formData.appId" placeholder="请输入appId" maxlength="255"/>
</el-form-item>
<el-form-item label="mch_id" prop="mchId">
<el-input v-model="formData.mchId" placeholder="请输入mchId" maxlength="255"/>
</el-form-item>
<el-form-item label="回调地址" prop="notifyUrl">
<el-input v-model="formData.notifyUrl" placeholder="请输入微信支付回调地址" maxlength="255"/>
</el-form-item>
<el-form-item label="私钥" prop="privateKeyStr">
<el-input type="textarea" v-model="formData.privateKeyStr" maxlength="900" placeholder="请输入私钥"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
@ -204,7 +217,11 @@ export default {
businessStartTime: null,
businessEndTime: null,
lat: null,
lgt: null
lgt: null,
appId: null,
mchId: null,
notifyUrl: null,
privateKeyStr: null,
},
//
formRules: {
@ -355,7 +372,11 @@ export default {
businessStartTime: null,
businessEndTime: null,
lat: null,
lgt: null
lgt: null,
appId: null,
mchId: null,
notifyUrl: null,
privateKeyStr: null,
}
//
this.lng = "";

View File

@ -11,6 +11,36 @@
<el-form-item label="业务经理" prop="businessName">
<el-input v-model="queryParams.businessName" placeholder="请输入业务经理姓名" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="订单状态" prop="paymentStatus">
<el-select
v-model="queryParams.paymentStatus"
placeholder="请选择订单状态"
clearable
@keyup.enter.native="handleQuery"
>
<el-option label="待支付" value="0" />
<el-option label="已取消" value="1" />
<el-option label="已支付(已报名)" value="2" />
<el-option label="待面签" value="3" />
<el-option label="已面签" value="4" />
<el-option label="已完成" value="5" />
<el-option label="申请退款" value="6" />
<el-option label="退款中" value="7" />
<el-option label="退款成功" value="8" />
</el-select>
</el-form-item>
<el-form-item label="是否面签" prop="isSign">
<el-select
v-model="queryParams.isSign"
placeholder="请选择面签状态"
clearable
@keyup.enter.native="handleQuery"
>
<el-option label="否" value="0" />
<el-option label="是" value="1" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
@ -92,7 +122,11 @@ export default {
pageSize: 10,
name: null,
phone: null,
type: null
type: null,
paymentStatus: null,
isSign: null,
businessName: null,
businessPhone: null,
},
};
},

View File

@ -82,3 +82,12 @@ export function getStudentDetail(userId) {
method: 'get'
})
}
export function getSourceUserById(userId) {
return request({
url: '/base/dl-drive-school-coach/getCoachByUserId?userId=' + userId,
method: 'get'
})
}

View File

@ -53,11 +53,13 @@
<!-- <span>{{ parseTime(scope.row.endTime) }}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="订单状态" align="center" prop="paymentStatus">
<template v-slot="scope">
<dict-tag :type="DICT_TYPE.DRIVE_SCHOOL_ORDER_STATUS" :value="scope.row.paymentStatus"/>
</template>
</el-table-column>
<el-table-column label="支付渠道" align="center" prop="payChannel" :formatter="formatPayChannel"/>
<el-table-column label="是否已面签" align="center" prop="isSign">
<template slot-scope="scope">
<el-tag v-if="scope.row.isSign == 1" type="success"></el-tag>
@ -70,6 +72,10 @@
<dict-tag :type="DICT_TYPE.DRIVE_SCHOOL_PAY_TYPE" :value="scope.row.payType"/>
</template>
</el-table-column>
<el-table-column label="报名时间" align="center" prop="createTime" :formatter="formatDate"/>
<el-table-column label="报名方式" align="center" prop="signType" :formatter="formatSignType"/>
<!-- <el-table-column label="学费到账审核" align="center" prop="receiptReview" :formatter="formatReceiptReview"/>-->
<el-table-column label="信息" align="center" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="viewStudentInfo(scope.row)">学员信息</el-button>
@ -136,7 +142,7 @@
</el-dialog>
<el-dialog :title="studentDialog.title" :visible.sync="studentDialog.visible" width="45%" v-dialogDrag append-to-body>
<el-form ref="formRef" :model="studentDialog.studentInfo" v-loading="studentDialog.loading" label-width="100px">
<el-form ref="studentFormRef" :model="studentDialog.studentInfo" v-loading="studentDialog.loading" label-width="100px">
<el-form-item label="头像" prop="avatar">
<el-image
v-if="studentDialog.studentInfo.avatar"
@ -149,12 +155,12 @@
<el-row>
<el-col :span="12">
<el-form-item label="姓名" prop="name">
<el-input v-model="studentDialog.studentInfo.name" placeholder="请输入姓名" :disabled="true"/>
<span class="display-text">{{ studentDialog.studentInfo.name || '-' }}</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="年龄" prop="age">
<el-input v-model="studentDialog.studentInfo.age" placeholder="请输入年龄" :disabled="true"/>
<span class="display-text">{{ studentDialog.studentInfo.age || '-' }}</span>
</el-form-item>
</el-col>
</el-row>
@ -162,16 +168,14 @@
<el-row>
<el-col :span="12">
<el-form-item label="性别" prop="sex">
<el-radio-group v-model="studentDialog.studentInfo.sex" disabled>
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_USER_SEX)"
:key="dict.value" :label="dict.value">{{ dict.label }}
</el-radio>
</el-radio-group>
<span class="display-text">
{{ getDictLabel(DICT_TYPE.SYSTEM_USER_SEX, studentDialog.studentInfo.sex) || '-' }}
</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系电话" prop="phone">
<el-input v-model="studentDialog.studentInfo.phone" placeholder="请输入联系电话" :disabled="true"/>
<span class="display-text">{{ studentDialog.studentInfo.phone || '-' }}</span>
</el-form-item>
</el-col>
</el-row>
@ -179,12 +183,12 @@
<el-row>
<el-col :span="12">
<el-form-item label="身份证号" prop="idCard">
<el-input v-model="studentDialog.studentInfo.idCard" placeholder="请输入身份证号" :disabled="true"/>
<span class="display-text">{{ studentDialog.studentInfo.idCard || '-' }}</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工作单位" prop="workName">
<el-input v-model="studentDialog.studentInfo.workName" placeholder="请输入工作单位" :disabled="true"/>
<span class="display-text">{{ studentDialog.studentInfo.workName || '-' }}</span>
</el-form-item>
</el-col>
</el-row>
@ -192,12 +196,30 @@
<el-row>
<el-col :span="12">
<el-form-item label="户籍地址" prop="registAddress">
<el-input v-model="studentDialog.studentInfo.registAddress" placeholder="请输入户籍地址" :disabled="true"/>
<span class="display-text">{{ studentDialog.studentInfo.registAddress || '-' }}</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="家庭住址" prop="address">
<el-input v-model="studentDialog.studentInfo.address" placeholder="请输入家庭住址" :disabled="true"/>
<span class="display-text">{{ studentDialog.studentInfo.address || '-' }}</span>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="渠道" prop="source">
<span class="display-text">{{ getSourceLabel(studentDialog.studentInfo.source) }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="招生人" prop="sourceUserId">
<span class="display-text">{{ sourceUser || studentDialog.studentInfo.sourceUserId || '-' }}</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="来源" prop="channel">
<span class="display-text">{{ studentDialog.studentInfo.channel || '-' }}</span>
</el-form-item>
</el-col>
</el-row>
@ -205,59 +227,11 @@
<el-row>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input type="textarea" v-model="studentDialog.studentInfo.remark" placeholder="请输入备注" :disabled="true"/>
<pre class="display-text remark-text">{{ studentDialog.studentInfo.remark || '-' }}</pre>
</el-form-item>
</el-col>
</el-row>
<!-- <el-form-item label="证件照" prop="idPhoto">
<div style="display: flex; flex-wrap: wrap; gap: 10px;">
<el-image
v-for="(photo, index) in getPhotoList(studentDialog.studentInfo.idPhoto)"
:key="index"
:src="baseImageUrl + photo"
style="width: 200px; height: 150px;"
:preview-src-list="getPhotoPreviewList(studentDialog.studentInfo.idPhoto)"
fit="contain"
/>
</div>
</el-form-item>
<el-form-item label="生活照" prop="lifePhoto">
<div style="display: flex; flex-wrap: wrap; gap: 10px;">
<el-image
v-for="(photo, index) in getPhotoList(studentDialog.studentInfo.lifePhoto)"
:key="'life-'+index"
:src="baseImageUrl + photo"
style="width: 200px; height: 150px;"
:preview-src-list="getPhotoPreviewList(studentDialog.studentInfo.lifePhoto)"
fit="contain"
/>
</div>
</el-form-item>
<el-form-item label="其他照片" prop="otherPhoto">
<div style="display: flex; flex-wrap: wrap; gap: 10px;">
<el-image
v-for="(photo, index) in getPhotoList(studentDialog.studentInfo.otherPhoto)"
:key="'other-'+index"
:src="baseImageUrl + photo"
style="width: 200px; height: 150px;"
:preview-src-list="getPhotoPreviewList(studentDialog.studentInfo.otherPhoto)"
fit="contain"
/>
</div>
</el-form-item>-->
<!-- <el-form-item label="体检报告" prop="examinationReport">
<div style="display: flex; flex-wrap: wrap; gap: 10px;">
<el-image
v-for="(photo, index) in getPhotoList(studentDialog.studentInfo.examinationReport)"
:key="'exam-'+index"
:src="baseImageUrl + photo"
style="width: 200px; height: 150px;"
:preview-src-list="getPhotoPreviewList(studentDialog.studentInfo.examinationReport)"
fit="contain"
/>
</div>
</el-form-item>-->
<el-form-item label="证件照" prop="idPhoto">
<div style="display: flex; flex-wrap: wrap; gap: 10px;">
<template v-if="getPhotoList(studentDialog.studentInfo.idPhoto).length > 0">
@ -348,6 +322,7 @@ import SchoolCourseOrderForm from '@/views/drivingSchool/DriveSchoolPay/form/Sch
import AssignmentCoach from "@/views/drivingSchool/DriveSchoolPay/form/assignmentCoach.vue";
import EndOrder from "@/views/drivingSchool/DriveSchoolPay/form/endOrder.vue";
import SchoolCourseOrderFastAddForm from "@/views/drivingSchool/DriveSchoolPay/form/SchoolCourseOrderFastAddForm.vue";
import { getSourceUserById } from '@/views/drivingSchool/DriveSchoolPay/api'
export default {
name: "SchoolCourseOrder",
components: {
@ -398,7 +373,9 @@ export default {
loading: false,
//
studentInfo: {}
}
},
sourceList: this.getDictDatas("drive_school_channel"),
sourceUser:null
};
},
created() {
@ -452,6 +429,14 @@ export default {
if (!photoStr) return [];
return photoStr.split(',').map(item => this.baseImageUrl + item.trim());
},
getSourceLabel(value) {
const item = this.sourceList.find(item => item.value === value);
return item ? item.label : value; //
},
getDictLabel(dictType, value) {
const dict = this.getDictDatas(dictType).find(item => item.value === value);
return dict ? dict.label : value;
},
/* async viewContract(row) {
try {
this.loading = true;
@ -464,6 +449,19 @@ export default {
this.loading = false;
}
}, */
getSourceUserId(userId){
getSourceUserById(userId).then(res => {
console.log(res)
this.sourceUser = res.data.name
})
},
formatReceiptReview(row, column, value) {
const map = {
1: '待审核',
0: '已审核'
};
return map[value] ?? '未知类型';
},
async viewContract(row) {
try {
this.loading = true;
@ -488,6 +486,9 @@ export default {
// API
const res = await SchoolCourseOrderApi.getStudentDetail(row.userId)
this.studentDialog.studentInfo = res.data
if(this.studentDialog.studentInfo.sourceUserId != null){
this.getSourceUserId(this.studentDialog.studentInfo.sourceUserId)
}
console.log('res',res.data)
} finally {
this.studentDialog.loading = false
@ -515,6 +516,54 @@ export default {
this.exportLoading = false;
}
},
formatDate(row, column, cellValue) {
return this.formatTimestampToDate(cellValue);
},
formatTimestampToDate(timestamp) {
if (!timestamp) return '';
const date = new Date(timestamp);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
},
formatPayChannel(row, column, value) {
const map = {
'1': '微信支付',
'2': '线下支付'
};
return map[value] ?? '-';
},
formatSignType(row, column, value) {
const map = {
'1': '代报名'
};
return map[value] ?? '-';
},
}
};
</script>
<style scoped>
.display-text {
display: inline-block;
padding: 0 15px;
line-height: 40px;
height: 40px;
border-radius: 4px;
background-color: #f5f7fa;
color: #606266;
width: 100%;
}
.remark-text {
white-space: pre-wrap;
min-height: 60px;
line-height: 1.5;
padding: 10px 15px;
}
</style>

View File

@ -35,7 +35,7 @@ export function getProcessAndBatch(id) {
}
// 获得驾校-学员课程进度分页
export function getprocessPage(params) {
export function getProcessPage(params) {
return request({
url: '/process/page',
method: 'get',

View File

@ -129,7 +129,7 @@ export default {
async getList() {
try {
this.loading = true;
const res = await processApi.getprocessPage(this.queryParams);
const res = await processApi.getProcessPage(this.queryParams);
this.list = res.data.records;
this.total = res.data.total;
} finally {

View File

@ -45,6 +45,8 @@
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="教练姓名" align="center" prop="coachName" />
<el-table-column label="学生姓名" align="center" prop="studentName" />
<el-table-column label="课程名称" align="center" prop="courseName" />
<el-table-column label="课程类型" align="center" prop="courseType" />
<el-table-column label="提成金额" align="center" prop="commissionAmount" />
<el-table-column label="科目" align="center" prop="subject" />
<el-table-column label="审核人姓名" align="center" prop="checkName" />

View File

@ -27,9 +27,9 @@ export function getprocess(id) {
}
// 获得驾校-学员课程进度分页
export function getprocessPage(params) {
export function getProcessPage(params) {
return request({
url: '/process/page',
url: '/process/newPage',
method: 'get',
params
})

View File

@ -272,6 +272,22 @@ export default {
async submitForm() {
//
await this.$refs["formRef"].validate();
if (this.formData.examStatus !== '1') {
try {
//
await this.$confirm('当前学员考试状态不是已通过状态,是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
});
// ""
} catch (error) {
// ""
return;
}
}
this.formLoading = true;
try {
const data = this.formData;

View File

@ -1,5 +1,32 @@
<template>
<div class="app-container">
<el-tabs v-model="activeTab" @tab-click="handleTabChange">
<!-- <el-tab-pane label="全部" name="all"></el-tab-pane>-->
<el-tab-pane label="待审核" name="null"></el-tab-pane>
<el-tab-pane label="已通过审核" name="1"></el-tab-pane>
<el-tab-pane label="未通过审核" name="0"></el-tab-pane>
</el-tabs>
<!-- <el-tabs v-model="activeTab" @tab-click="handleTabChange">
<el-tab-pane label="全部" name="all"></el-tab-pane>
<el-tab-pane label="待审核" name="null"></el-tab-pane>
<el-tab-pane label="已审核">
<template #label>
<el-dropdown @command="handleAuditedTabChange" trigger="click">
<span class="el-dropdown-link">
已审核<el-icon class="el-icon&#45;&#45;right"><arrow-down /></el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="1">已通过</el-dropdown-item>
<el-dropdown-item command="0">未通过</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</el-tab-pane>
</el-tabs>-->
<!-- 搜索工作栏 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="课程名称" prop="courseName">
@ -25,6 +52,15 @@
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="openForm(undefined)">新增</el-button>
</el-col>
<el-col :span="1.5" style="display: flex; align-items: center;">
<span style="margin-right: 10px; font-size: 14px;">只显示已通过考试学员</span>
<el-switch
v-model="showPassedOnly"
active-color="#13ce66"
inactive-color="#dcdfe6"
@change="togglePassedStudents"
/>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
@ -65,6 +101,7 @@
<span v-if="scope.row.financePass == 0">未通过</span>
</template>
</el-table-column>
<el-table-column label="财务审核备注" width="120" align="center" prop="financeRemark"/>
<el-table-column label="操作" width="120" align="center" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.id,true)">查看</el-button>
@ -83,13 +120,17 @@
<script>
import * as processApi from '@/views/drivingSchool/process/api';
import processForm from '@/views/drivingSchool/process/form/processForm.vue';
// import { ArrowDown } from '@/element-plus/icons-vue';
export default {
name: "process",
components: {
processForm,
// ArrowDown
},
data() {
return {
activeTab: 'all',
showPassedOnly: false,
//
loading: true,
//
@ -114,9 +155,12 @@ export default {
coachName: null,
userName: null,
studentIdCard:null,
financePass: undefined,
examStatus:undefined,
},
};
},
created() {
this.getList();
},
@ -125,13 +169,14 @@ export default {
async getList() {
try {
this.loading = true;
const res = await processApi.getprocessPage(this.queryParams);
const res = await processApi.getProcessPage(this.queryParams);
this.list = res.data.records;
this.total = res.data.total;
} finally {
this.loading = false;
}
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
@ -140,6 +185,8 @@ export default {
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.showPassedOnly = false;
this.queryParams.examStatus = undefined;
this.handleQuery();
},
/** 添加/修改操作 */
@ -168,7 +215,41 @@ export default {
this.exportLoading = false;
}
},
/** Tab切换事件 */
handleTabChange(tab) {
this.queryParams.pageNo = 1;
if (tab.paneName === 'all') {
this.queryParams.financePass = '1';
} else {
this.queryParams.financePass = tab.paneName === 'null' ? null : tab.paneName;
}
this.getList();
},
/** 切换是否只显示已通过考试的学员 */
togglePassedStudents() {
this.queryParams.pageNo = 1;
this.queryParams.examStatus = this.showPassedOnly ? '1' : undefined;
this.getList();
},
/* handleTabChange(tab) {
this.queryParams.pageNo = 1;
if (tab.paneName === 'all') {
this.queryParams.financePass = undefined;
} else {
this.queryParams.financePass = tab.paneName === 'null' ? null : undefined;
}
this.getList();
},
/!** 已审核Tab下的子选项切换事件 *!/
handleAuditedTabChange(command) {
this.activeTab = 'audited'; //
this.queryParams.pageNo = 1;
this.queryParams.financePass = command === '1' ? true : false;
this.getList();
} */
}
};
</script>

View File

@ -27,7 +27,7 @@
<el-input type="textarea" v-model="formData.reportContent" :autosize="{ minRows: 6, maxRows: 10 }"/>
</el-form-item>
<el-form-item label="汇报附件" prop="reportFiles">
<insp-file-upload
<drive-file-upload
:fileSize="30"
:fileType="['doc', 'xls', 'ppt', 'txt', 'pdf','png','jpg','jpeg','gif','docx','xlsx','pptx','wps']"
v-model="formData.filePath"/>

View File

@ -44,6 +44,19 @@
</el-table-column>
<el-table-column label="汇报内容" align="center" prop="reportContent" show-overflow-tooltip/>
<el-table-column label="汇报人" align="center" prop="userName"/>
<el-table-column label="附件" align="center" width="100">
<template v-slot="scope">
<el-button
v-if="scope.row.filePath"
size="mini"
type="text"
@click="handleViewFiles(scope.row.filePath)"
>
查看附件
</el-button>
<span v-else>无附件</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="workReportView(scope.row.id)">打印
@ -56,11 +69,60 @@
</el-table-column>
</el-table>
<el-dialog :visible.sync="showView" width="50%" center>
<div v-html="htmText" id="printMe"></div>
<el-button type="primary" style="margin-left: 90%;margin-top:20px " v-print="'#printMe'" size="small">打印
</el-button>
<el-dialog :title="'文件预览(' + currentFileName + ''" :visible.sync="fileDialogVisible" width="70%" append-to-body>
<div class="preview-container">
<!-- 左侧预览区域 -->
<!-- 音频文件 -->
<audio v-if="isAudioType" class="preview-iframe" controls>
<source :src="currentFileUrl"/>
</audio>
<!-- Office文档/文本/PDF -->
<iframe
v-else-if="!isImageType && currentFileType !== 'txt' && !isAudioType && currentFileType !== 'pdf'"
:src="officePreviewUrl"
frameborder="0"
class="preview-iframe"
></iframe>
<!-- 图片预览 -->
<image-preview
v-else-if="isImageType"
class="preview-iframe"
:src="currentFileUrl"
></image-preview>
<!-- PDF/文本 -->
<iframe
v-else-if="currentFileType === 'txt' || currentFileType === 'pdf'"
:src="currentFileUrl"
frameborder="0"
class="preview-iframe"
></iframe>
<!-- 右侧文件列表 -->
<div class="file-list" v-if="currentFileList.length > 1">
<el-table
:data="currentFileList"
height="100%"
@row-click="handleFileClick"
:row-class-name="getRowClassName">
<el-table-column
prop="fileName"
label="文件列表"
min-width="180">
<template #default="{ row }">
<div class="file-item">
<i :class="getFileIcon(row)"></i>
{{ getFileName(row) }}
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
</el-dialog>
<!-- 分页组件 -->
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
@pagination="getList"/>
@ -115,8 +177,26 @@ export default {
servicePackageId: "jiaxiao",
dictType:'drive_school_report_role',
},
fileDialogVisible: false,
currentFileList: [],
activeFileTab: 0,
baseUrl: process.env.VUE_APP_BASE_API,
currentFileUrl: '',
currentFileName: '',
currentFileType: '',
officePreviewUrl: '',
};
},
computed: {
isImageType() {
return /\.(jpg|jpeg|png|gif|webp|bmp)$/i.test(this.currentFileUrl);
},
isAudioType() {
const audioExtensions = ['mp3', 'wav', 'ogg', 'aac', 'm4a', 'flac'];
return audioExtensions.some(ext => this.currentFileUrl.endsWith(ext));
}
},
created() {
this.getList();
},
@ -175,6 +255,123 @@ export default {
this.exportLoading = false;
}
},
//
handleViewFiles(filePath) {
if (!filePath) {
this.$message.warning('没有附件');
return;
}
//
this.currentFileList = filePath.split(',').filter(item => item.trim());
this.fileDialogVisible = true;
//
if (this.currentFileList.length > 0) {
this.previewFile(this.currentFileList[0]);
}
},
// URLAPI
getFullFileUrl(filePath) {
if (!filePath) return '';
// URLbase64
if (filePath.startsWith('http') || filePath.startsWith('data:')) {
return filePath;
}
// API
const baseUrl = 'http://122.51.230.86:9000/' || '';
return `${baseUrl.replace(/\/$/, '')}/${filePath.replace(/^\//, '')}`;
},
//
getFileName(filePath) {
return filePath.split('/').pop() || '未命名文件';
},
//
isImage(filePath) {
return /\.(jpg|jpeg|png|gif|webp|bmp)$/i.test(filePath);
},
//
previewFile(filePath) {
this.currentFileUrl = this.getFullFileUrl(filePath);
this.currentFileName = this.getFileName(filePath);
this.currentFileType = this.getFileExtension(filePath);
// OfficeURL
this.officePreviewUrl = 'https://view.officeapps.live.com/op/view.aspx?src=' +
encodeURIComponent(this.currentFileUrl);
},
//
getFileExtension(filePath) {
return filePath.split('.').pop().toLowerCase();
},
//
getFileIcon(filePath) {
return this.isImage(filePath) ? 'el-icon-picture' : 'el-icon-document';
},
//
handleFileClick(row) {
this.previewFile(row);
},
//
getRowClassName({row}) {
return row === this.currentFileUrl ? 'highlight-row' : '';
},
}
};
</script>
<style scoped>
.image-preview {
display: flex;
justify-content: center;
margin: 20px 0;
}
.image-preview img {
max-height: 500px;
max-width: 100%;
border: 1px solid #eee;
}
.preview-container {
display: flex;
height: 70vh;
}
.preview-iframe {
flex: 1;
width: 100%;
height: 100%;
border: none;
}
.file-list {
flex: 0 0 250px;
border-left: 1px solid #ebeef5;
padding-left: 10px;
margin-left: 10px;
}
.file-item {
cursor: pointer;
padding: 8px;
transition: background 0.3s;
}
.file-item:hover {
background: #f5f7fa;
}
.highlight-row {
background-color: #f0f7ff;
}
</style>

View File

@ -1,235 +1,28 @@
<template>
<div class="container_">
<!-- <div class="top-list">-->
<!-- <div class="list-box" v-for="(item, index) in serviceList" :key="item.id" :span="4">-->
<!-- <div @click="goRoute(item.id)">-->
<!-- <img :src="imgUrl + item.coverImg"-->
<!-- style="width: 300px; height: 300px;">-->
<!-- <div style="font-weight: bold;text-align: center;font-size: 28px">{{ item.name }}</div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<div class="container-box">
<div class="flex-box">
<div style=" font-size: 30px;margin-bottom: 30px">临期提醒</div>
<el-table
:data="warnList"
stripe
style="width: 100%">
<el-table-column
prop="title"
label="标题"
width="180">
</el-table-column>
<el-table-column
prop="content"
label="内容"
width="180">
</el-table-column>
<el-table-column
prop="warnTime"
label="提醒时间">
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination v-show="warnTotal > 0" :total="warnTotal" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
@pagination="getWarnList"
/>
</div>
<div class="flex-box">
<div style="font-size: 30px;margin-bottom: 30px">消息通知</div>
<el-table
:data="messageList"
stripe
style="width: 100%">
<el-table-column
prop="templateNickname"
label="发送人"
width="120">
</el-table-column>
<el-table-column label="发送时间" align="center" prop="createTime" width="180">
<template v-slot="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="类型" align="center" prop="templateType" width="80">
<template v-slot="scope">
<dict-tag :type="DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE" :value="scope.row.templateType" />
</template>
</el-table-column>
<el-table-column
prop="templateContent"
label="内容">
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination v-show="messageTotal > 0" :total="messageTotal" :page.sync="messageQueryParams.pageNo"
:limit.sync="messageQueryParams.pageSize"
@pagination="getNotifyMessage"
/>
</div>
</div>
<img class="fullscreen-image" src="@/assets/images/homeImg.png" alt="首页图片">
</div>
</template>
<script>
import PanelGroup from './dashboard/PanelGroup'
import LineChart from './dashboard/LineChart'
import RaddarChart from './dashboard/RaddarChart'
import PieChart from './dashboard/PieChart'
import BarChart from './dashboard/BarChart'
import {getServicePackageList} from "@/api/system/servicePackage";
import {warnList,getMyNotifyMessagePage} from "@/api/system/notify/message";
const lineChartData = {
newVisitis: {
expectedData: [100, 120, 161, 134, 105, 160, 165],
actualData: [120, 82, 91, 154, 162, 140, 145]
},
messages: {
expectedData: [200, 192, 120, 144, 160, 130, 140],
actualData: [180, 160, 151, 106, 145, 150, 130]
},
purchases: {
expectedData: [80, 100, 121, 104, 105, 90, 100],
actualData: [120, 90, 100, 138, 142, 130, 130]
},
shoppings: {
expectedData: [130, 140, 141, 142, 145, 150, 160],
actualData: [120, 82, 91, 154, 162, 140, 130]
}
}
export default {
name: 'Index',
components: {
PanelGroup,
LineChart,
RaddarChart,
PieChart,
BarChart
},
data() {
return {
imgUrl:'',
lineChartData: lineChartData.newVisitis,
serviceList: [],
warnList: [],
messageList: [],
queryParams: {
pageNo: 1,
pageSize: 10
},
messageQueryParams: {
pageNo: 1,
pageSize: 10
},
messageTotal: 0,
warnTotal: 0
}
},
created() {
this.getServiceList()
this.getNotifyMessage()
this.getWarnList()
this.imgUrl = process.env.VUE_APP_IMAGE_URL
console.log( this.imgUrl + '1111111' )
},
methods: {
handleSetLineChartData(type) {
this.lineChartData = lineChartData[type]
},
goRoute(code){
console.log(window.location.host,150)
window.open(window.location.origin+"/index?routeCode="+code)
},
getNotifyMessage() {
//
getMyNotifyMessagePage(this.messageQueryParams).then(response => {
this.messageList = response.data.list;
this.messageTotal = response.data.total;
});
},
getWarnList() {
//
warnList(this.queryParams).then(response => {
console.log(response,149)
this.warnList = response.data.records;
this.warnTotal = response.data.total;
});
},
getServiceList() {
getServicePackageList(this.queryParams).then(response => {
this.serviceList = response.data;
});
}
}
name: 'Index'
}
</script>
<style lang="scss" scoped>
.container_{
background-color: rgb(240, 242, 245);
box-sizing: border-box;
padding: 15px;
}
.top-list{
.container_ {
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 25px;
flex-wrap: wrap;
}
.list-box{
background: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 4px;
box-sizing: border-box;
padding: 15px;
border-radius: 8px;
}
.container-box{
width: 100%;
display: flex;
justify-content: space-between;
}
.flex-box{
width: 49%;
background: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 4px;
box-sizing: border-box;
padding: 15px;
border-radius: 8px;
}
.dashboard-editor-container {
padding: 32px;
background-color: rgb(240, 242, 245);
position: relative;
height: calc(100vh - 100px);
margin: 0;
padding: 5px;
overflow: hidden;
.chart-wrapper {
background: #fff;
padding: 16px 16px 0;
margin-bottom: 32px;
}
}
@media (max-width: 1024px) {
.chart-wrapper {
padding: 8px;
.fullscreen-image {
width: 100%;
height: 100%;
//object-fit: cover;
object-fit: fill;
}
}
</style>

235
src/views/index1.vue Normal file
View File

@ -0,0 +1,235 @@
<template>
<div class="container_">
<!-- <div class="top-list">-->
<!-- <div class="list-box" v-for="(item, index) in serviceList" :key="item.id" :span="4">-->
<!-- <div @click="goRoute(item.id)">-->
<!-- <img :src="imgUrl + item.coverImg"-->
<!-- style="width: 300px; height: 300px;">-->
<!-- <div style="font-weight: bold;text-align: center;font-size: 28px">{{ item.name }}</div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<div class="container-box">
<div class="flex-box">
<div style=" font-size: 30px;margin-bottom: 30px">临期提醒</div>
<el-table
:data="warnList"
stripe
style="width: 100%">
<el-table-column
prop="title"
label="标题"
width="180">
</el-table-column>
<el-table-column
prop="content"
label="内容"
width="180">
</el-table-column>
<el-table-column
prop="warnTime"
label="提醒时间">
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination v-show="warnTotal > 0" :total="warnTotal" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
@pagination="getWarnList"
/>
</div>
<div class="flex-box">
<div style="font-size: 30px;margin-bottom: 30px">消息通知</div>
<el-table
:data="messageList"
stripe
style="width: 100%">
<el-table-column
prop="templateNickname"
label="发送人"
width="120">
</el-table-column>
<el-table-column label="发送时间" align="center" prop="createTime" width="180">
<template v-slot="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="类型" align="center" prop="templateType" width="80">
<template v-slot="scope">
<dict-tag :type="DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE" :value="scope.row.templateType" />
</template>
</el-table-column>
<el-table-column
prop="templateContent"
label="内容">
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination v-show="messageTotal > 0" :total="messageTotal" :page.sync="messageQueryParams.pageNo"
:limit.sync="messageQueryParams.pageSize"
@pagination="getNotifyMessage"
/>
</div>
</div>
</div>
</template>
<script>
import PanelGroup from './dashboard/PanelGroup'
import LineChart from './dashboard/LineChart'
import RaddarChart from './dashboard/RaddarChart'
import PieChart from './dashboard/PieChart'
import BarChart from './dashboard/BarChart'
import {getServicePackageList} from "@/api/system/servicePackage";
import {warnList,getMyNotifyMessagePage} from "@/api/system/notify/message";
const lineChartData = {
newVisitis: {
expectedData: [100, 120, 161, 134, 105, 160, 165],
actualData: [120, 82, 91, 154, 162, 140, 145]
},
messages: {
expectedData: [200, 192, 120, 144, 160, 130, 140],
actualData: [180, 160, 151, 106, 145, 150, 130]
},
purchases: {
expectedData: [80, 100, 121, 104, 105, 90, 100],
actualData: [120, 90, 100, 138, 142, 130, 130]
},
shoppings: {
expectedData: [130, 140, 141, 142, 145, 150, 160],
actualData: [120, 82, 91, 154, 162, 140, 130]
}
}
export default {
name: 'Index',
components: {
PanelGroup,
LineChart,
RaddarChart,
PieChart,
BarChart
},
data() {
return {
imgUrl:'',
lineChartData: lineChartData.newVisitis,
serviceList: [],
warnList: [],
messageList: [],
queryParams: {
pageNo: 1,
pageSize: 10
},
messageQueryParams: {
pageNo: 1,
pageSize: 10
},
messageTotal: 0,
warnTotal: 0
}
},
created() {
this.getServiceList()
this.getNotifyMessage()
this.getWarnList()
this.imgUrl = process.env.VUE_APP_IMAGE_URL
console.log( this.imgUrl + '1111111' )
},
methods: {
handleSetLineChartData(type) {
this.lineChartData = lineChartData[type]
},
goRoute(code){
console.log(window.location.host,150)
window.open(window.location.origin+"/index?routeCode="+code)
},
getNotifyMessage() {
//
getMyNotifyMessagePage(this.messageQueryParams).then(response => {
this.messageList = response.data.list;
this.messageTotal = response.data.total;
});
},
getWarnList() {
//
warnList(this.queryParams).then(response => {
console.log(response,149)
this.warnList = response.data.records;
this.warnTotal = response.data.total;
});
},
getServiceList() {
getServicePackageList(this.queryParams).then(response => {
this.serviceList = response.data;
});
}
}
}
</script>
<style lang="scss" scoped>
.container_{
background-color: rgb(240, 242, 245);
box-sizing: border-box;
padding: 15px;
}
.top-list{
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 25px;
flex-wrap: wrap;
}
.list-box{
background: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 4px;
box-sizing: border-box;
padding: 15px;
border-radius: 8px;
}
.container-box{
width: 100%;
display: flex;
justify-content: space-between;
}
.flex-box{
width: 49%;
background: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 4px;
box-sizing: border-box;
padding: 15px;
border-radius: 8px;
}
.dashboard-editor-container {
padding: 32px;
background-color: rgb(240, 242, 245);
position: relative;
.chart-wrapper {
background: #fff;
padding: 16px 16px 0;
margin-bottom: 32px;
}
}
@media (max-width: 1024px) {
.chart-wrapper {
padding: 8px;
}
}
</style>

View File

@ -9,7 +9,7 @@
<div class="field">
<!-- [移动端]标题 -->
<h2 class="mobile-title">
<h3 class="title">后台管理系统</h3>
<h3 class="title">管理系统</h3>
</h2>
<!-- 表单 -->

View File

@ -9,7 +9,7 @@
<div class="field">
<!-- [移动端]标题 -->
<h2 class="mobile-title">
<h3 class="title">"车联通"后台管理系统</h3>
<h3 class="title">"车联通"管理系统</h3>
</h2>
<!-- 表单 -->