Merge remote-tracking branch 'origin/master'

This commit is contained in:
sunhaoyuan 2025-11-28 16:39:08 +08:00
commit e6703288a4
5 changed files with 732 additions and 102 deletions

View File

@ -0,0 +1,638 @@
<template>
<el-dialog
:title="dialogTitle"
:visible.sync="visible"
:width="dialogWidth"
:fullscreen="isFullscreen"
append-to-body
@close="handleClose"
class="file-preview-dialog"
>
<!-- 工具栏 -->
<div class="preview-toolbar">
<el-button-group>
<el-button
size="mini"
icon="el-icon-circle-close"
@click="closePreview"
>
关闭
</el-button>
<el-button
size="mini"
:icon="isFullscreen ? 'el-icon-close' : 'el-icon-full-screen'"
@click="toggleFullscreen"
>
{{ isFullscreen ? '退出全屏' : '全屏' }}
</el-button>
<el-button
size="mini"
icon="el-icon-download"
@click="handleDownload"
v-if="selectFile.downloadable !== false"
>
下载
</el-button>
<el-button
size="mini"
icon="el-icon-refresh-left"
@click="handleRefresh"
v-if="showRefresh"
>
刷新
</el-button>
<!-- 新增文件列表切换按钮 -->
<el-button
size="mini"
icon="el-icon-tickets"
@click="toggleFileList"
v-if="hasMultipleFiles"
>
{{ showFileList ? '隐藏列表' : '显示列表' }}
</el-button>
</el-button-group>
</div>
<div class="preview-container" ref="previewContainer">
<!-- 左侧预览区域 -->
<div class="preview-content" :class="{ 'has-sidebar': showFileList && hasMultipleFiles }">
<!-- 加载状态 -->
<div v-if="loading" class="preview-loading">
<i class="el-icon-loading loading-icon"></i>
<div>加载中...</div>
</div>
<!-- 不支持预览的提示 -->
<div v-else-if="!supportedType" class="preview-unsupported">
<i class="el-icon-document unsupported-icon"></i>
<div>暂不支持预览该文件类型</div>
<el-button type="primary" @click="handleDownload" v-if="selectFile.downloadable !== false">
下载文件
</el-button>
</div>
<!-- 各种文件类型的预览 -->
<template v-else>
<!-- 图片预览 -->
<image-preview
v-if="fileType === 'image'"
:src="fileUrl"
:preview-src-list="imagePreviewList"
class="preview-item"
/>
<!-- 音频预览 -->
<audio
v-else-if="fileType === 'audio'"
:src="fileUrl"
controls
class="preview-item audio-player"
/>
<!-- 视频预览 -->
<video
v-else-if="fileType === 'video'"
:src="fileUrl"
controls
class="preview-item video-player"
/>
<!-- PDF预览 -->
<iframe
v-else-if="fileType === 'pdf'"
:src="pdfViewerUrl"
frameborder="0"
class="preview-item"
/>
<!-- Office文档预览 -->
<iframe
v-else-if="fileType === 'office'"
:src="officeViewerUrl"
frameborder="0"
class="preview-item"
/>
<!-- 文本文件预览 -->
<div
v-else-if="fileType === 'text'"
class="preview-item text-preview"
>
<pre v-if="textContent">{{ textContent }}</pre>
<div v-else class="text-loading">加载文本内容...</div>
</div>
<!-- 代码文件预览 -->
<div
v-else-if="fileType === 'code'"
class="preview-item code-preview"
>
<pre><code v-html="highlightedCode"></code></pre>
</div>
<!-- 默认iframe预览 -->
<iframe
v-else
:src="fileUrl"
frameborder="0"
class="preview-item"
/>
</template>
</div>
<!-- 右侧文件列表 -->
<div class="file-sidebar" v-if="showFileList && hasMultipleFiles">
<div class="sidebar-header">
<span>文件列表 ({{ fileList.length }})</span>
<el-button
type="text"
icon="el-icon-close"
@click="showFileList = false"
/>
</div>
<div class="file-list">
<div
v-for="file in fileList"
:key="file.id || file.name"
:class="['file-item', { active: isActiveFile(file) }]"
@click="handleFileSelect(file)"
>
<i class="file-icon" :class="getFileIcon(file)"></i>
<span class="file-name" :title="file.fileName || file.name">
{{ file.fileName || file.name }}
</span>
<!-- 新增选中标记 -->
<i v-if="isActiveFile(file)" class="el-icon-check active-checkmark"></i>
</div>
</div>
</div>
</div>
</el-dialog>
</template>
<script>
//
const FILE_TYPES = {
image: ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'],
audio: ['mp3', 'wav', 'ogg', 'aac', 'm4a', 'flac', 'wma'],
video: ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm', 'm3u8'],
pdf: ['pdf'],
office: ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'],
text: ['txt', 'log', 'ini', 'conf'],
code: ['js', 'jsx', 'ts', 'tsx', 'vue', 'html', 'css', 'scss', 'java', 'py', 'php', 'json', 'xml']
}
//
const FILE_ICONS = {
image: 'el-icon-picture',
audio: 'el-icon-headset',
video: 'el-icon-video-play',
pdf: 'el-icon-document-checked',
office: 'el-icon-document-checked',
text: 'el-icon-document',
code: 'el-icon-document',
default: 'el-icon-document'
}
export default {
name: 'FilePreview',
props: {
//
fileList: {
type: Array,
default: () => []
},
// URL
baseUrl: {
type: String,
default: ''
},
// URL
previewUrl: {
type: String,
default: ''
},
// URL
fileServiceUrl: {
type: String,
default: ''
},
// Office
officeViewer: {
type: String,
default: 'https://view.officeapps.live.com/op/view.aspx?src='
},
// PDF
pdfViewer: {
type: String,
default: ''
},
//
width: {
type: String,
default: '80%'
},
//
showFileListByDefault: {
type: Boolean,
default: true
},
//
customFileTypeDetector: {
type: Function,
default: null
}
},
data() {
return {
visible: false,
isFullscreen: false,
showFileList: this.showFileListByDefault,
loading: false,
selectFile: {},
textContent: '',
highlightedCode: ''
}
},
computed: {
dialogTitle() {
return `文件预览(${this.selectFile.fileName || this.selectFile.name || ''}`
},
dialogWidth() {
return this.isFullscreen ? '100%' : this.width
},
fileType() {
if (this.customFileTypeDetector) {
return this.customFileTypeDetector(this.selectFile)
}
return this.detectFileType(this.selectFile)
},
supportedType() {
return this.fileType && this.fileType !== 'unsupported'
},
fileUrl() {
return this.getFileUrl(this.selectFile.filePath || this.selectFile.url)
},
officeViewerUrl() {
return this.officeViewer + encodeURIComponent(this.fileUrl)
},
pdfViewerUrl() {
if (this.pdfViewer) {
return this.pdfViewer + encodeURIComponent(this.fileUrl)
}
return this.fileUrl
},
imagePreviewList() {
return this.filteredFileList
.filter(file => this.detectFileType(file) === 'image')
.map(file => this.getFileUrl(file.filePath || file.url))
},
showRefresh() {
return ['office', 'pdf'].includes(this.fileType)
},
//
hasMultipleFiles() {
return this.fileList && this.fileList.length > 1
},
//
filteredFileList() {
return this.fileList || []
}
},
methods: {
//
async openPreview(file, fileList = null) {
this.selectFile = { ...file }
//
if (fileList) {
this.$emit('update:fileList', fileList)
}
//
this.showFileList = this.showFileListByDefault && this.hasMultipleFiles
this.visible = true
this.loading = true
try {
//
if (this.fileType === 'text' || this.fileType === 'code') {
await this.loadTextContent()
}
} catch (error) {
console.error('文件加载失败:', error)
} finally {
this.loading = false
}
},
//
closePreview() {
this.visible = false
this.isFullscreen = false
this.selectFile = {}
this.textContent = ''
this.highlightedCode = ''
},
//
detectFileType(file) {
const fileName = file.fileName || file.name || ''
const filePath = file.filePath || file.url || ''
const extension = this.getFileExtension(fileName || filePath).toLowerCase()
for (const [type, extensions] of Object.entries(FILE_TYPES)) {
if (extensions.includes(extension)) {
return type
}
}
// MIME
if (file.fileType) {
if (file.fileType.startsWith('image/')) return 'image'
if (file.fileType.startsWith('audio/')) return 'audio'
if (file.fileType.startsWith('video/')) return 'video'
if (file.fileType === 'application/pdf') return 'pdf'
}
return 'unsupported'
},
//
getFileExtension(filename) {
return filename.slice((filename.lastIndexOf('.') - 1 >>> 0) + 2)
},
// URL
getFileUrl(filePath) {
if (!filePath) return ''
// URL
if (filePath.includes('://')) {
return filePath
}
// URL
const baseUrl = this.fileServiceUrl || this.baseUrl
if (baseUrl) {
return baseUrl + (filePath.startsWith('/') ? filePath : '/' + filePath)
}
return filePath
},
//
getFileIcon(file) {
const fileType = this.detectFileType(file)
return FILE_ICONS[fileType] || FILE_ICONS.default
},
//
async loadTextContent() {
try {
const response = await fetch(this.fileUrl)
this.textContent = await response.text()
//
if (this.fileType === 'code') {
this.highlightCode()
}
} catch (error) {
console.error('加载文本内容失败:', error)
this.textContent = '无法加载文件内容'
}
},
// 使highlight.js
highlightCode() {
// highlight.js
this.highlightedCode = this.escapeHtml(this.textContent)
},
// HTML
escapeHtml(text) {
const div = document.createElement('div')
div.textContent = text
return div.innerHTML
},
//
toggleFullscreen() {
this.isFullscreen = !this.isFullscreen
},
//
handleDownload() {
const link = document.createElement('a')
link.href = this.fileUrl
link.download = this.selectFile.fileName || this.selectFile.name || 'download'
link.target = '_blank'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
},
//
handleRefresh() {
//
this.openPreview(this.selectFile)
},
//
handleFileSelect(file) {
if (this.isActiveFile(file)) return //
this.openPreview(file)
},
//
isActiveFile(file) {
if (file.id && this.selectFile.id) {
return file.id === this.selectFile.id
}
// id使
const fileKey = `${file.fileName || file.name}-${file.filePath || file.url}`
const selectFileKey = `${this.selectFile.fileName || this.selectFile.name}-${this.selectFile.filePath || this.selectFile.url}`
return fileKey === selectFileKey
},
//
handleClose() {
this.closePreview()
this.$emit('close')
},
//
toggleFileList() {
this.showFileList = !this.showFileList
}
}
}
</script>
<style scoped>
.file-preview-dialog {
:deep(.el-dialog__body) {
padding: 0;
position: relative;
}
}
.preview-toolbar {
position: absolute;
top: 10px;
right: 20px;
z-index: 1000;
background: rgba(255, 255, 255, 0.9);
padding: 8px;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.preview-container {
display: flex;
height: 80vh;
}
.preview-content {
flex: 1;
position: relative;
transition: all 0.3s ease;
&.has-sidebar {
flex: 0 0 75%;
}
}
.preview-loading,
.preview-unsupported {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
color: #909399;
}
.loading-icon,
.unsupported-icon {
font-size: 48px;
margin-bottom: 16px;
}
.preview-item {
width: 100%;
height: 100%;
border: none;
}
.audio-player,
.video-player {
background: #000;
}
.text-preview,
.code-preview {
padding: 20px;
overflow: auto;
background: #f8f9fa;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 14px;
line-height: 1.5;
}
.code-preview {
background: #1e1e1e;
color: #d4d4d4;
}
.file-sidebar {
flex: 0 0 25%;
border-left: 1px solid #e4e7ed;
display: flex;
flex-direction: column;
background: #fff;
transition: all 0.3s ease;
}
.sidebar-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
border-bottom: 1px solid #e4e7ed;
font-weight: 500;
background: #f8f9fa;
}
.file-list {
flex: 1;
overflow-y: auto;
padding: 8px 0;
}
.file-item {
display: flex;
align-items: center;
padding: 10px 16px;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
border-left: 3px solid transparent;
&:hover {
background-color: #f5f7fa;
}
&.active {
background-color: #ecf5ff;
color: #409eff;
border-left-color: #409eff;
.file-icon {
color: #409eff;
}
}
}
.file-icon {
margin-right: 8px;
font-size: 16px;
color: #909399;
}
.file-name {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: block; /* 保证文字显示 */
width: 20px;
}
/* 新增:选中标记样式 */
.active-checkmark {
color: #67c23a;
font-size: 14px;
font-weight: bold;
margin-left: 8px;
}
/* 响应式设计 */
@media (max-width: 768px) {
.preview-container {
flex-direction: column;
}
.file-sidebar {
flex: 0 0 200px;
border-left: none;
border-top: 1px solid #e4e7ed;
}
.preview-content.has-sidebar {
flex: 0 0 calc(100% - 200px);
}
}
</style>

View File

@ -3,18 +3,15 @@
<!-- 搜索工作栏 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="汇报主题" prop="reportTopic">
<el-input v-model="queryParams.reportTopic" placeholder="请输入汇报主题" clearable
@keyup.enter.native="handleQuery"/>
<el-input v-model="queryParams.reportTopic" placeholder="请输入汇报主题" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="汇报时间" prop="reportTime">
<el-date-picker v-model="queryParams.reportTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"/>
type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']" />
</el-form-item>
<el-form-item label="汇报人" prop="userId">
<el-input v-model="queryParams.userName" placeholder="请输入汇报人" clearable
@keyup.enter.native="handleQuery"/>
<el-input v-model="queryParams.userName" placeholder="请输入汇报人" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
@ -30,29 +27,24 @@
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
:loading="exportLoading">导出
:loading="exportLoading">导出
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="汇报主题" align="center" prop="reportTopic"/>
<el-table-column label="汇报主题" align="center" prop="reportTopic" />
<el-table-column label="汇报时间" align="center" prop="reportTime" width="180">
<template v-slot="scope">
<span>{{ parseTime(scope.row.reportTime) }}</span>
</template>
</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" 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 v-if="scope.row.filePath" size="mini" type="text" @click="handleViewFiles(scope.row.filePath)">
查看附件
</el-button>
<span v-else>无附件</span>
@ -60,7 +52,8 @@
</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)">查看<span style="font-weight: bold;font-size: 16px">|</span>打印
<el-button size="mini" type="text" icon="el-icon-edit" @click="workReportView(scope.row.id)">查看<span
style="font-weight: bold;font-size: 16px">|</span>打印
</el-button>
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.id)">修改
</el-button>
@ -70,49 +63,32 @@
</el-table-column>
</el-table>
<el-dialog :title="'文件预览(' + currentFileName + ''" :visible.sync="fileDialogVisible" width="70%"
append-to-body>
<file-preview ref="filePreview" :file-list="currentFileList"/>
<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"/>
<source :src="currentFileUrl" />
</audio>
<!-- Office文档/文本/PDF -->
<iframe
v-else-if="!isImageType && currentFileType !== 'txt' && !isAudioType && currentFileType !== 'pdf'"
:src="officePreviewUrl"
frameborder="0"
class="preview-iframe"
></iframe>
<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>
<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>
<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"
<el-table :data="currentFileList" height="100%" @row-click="handleFileClick"
:row-class-name="getRowClassName">
<el-table-column
prop="fileName"
label="文件列表"
min-width="180">
<el-table-column prop="fileName" label="文件列表" min-width="180">
<template #default="{ row }">
<div class="file-item">
<i :class="getFileIcon(row)"></i>
@ -134,10 +110,10 @@
<!-- 分页组件 -->
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
@pagination="getList"/>
@pagination="getList" />
<!-- 对话框(添加 / 修改) -->
<ReportForm ref="formRef" :servicePackageId="queryParams.servicePackageId" :dictType="reportToDictType"
@success="getList"/>
@success="getList" />
</div>
</template>
@ -145,7 +121,9 @@
import * as ReportApi from '@/views/drivingSchool/workReport/api/index';
import ReportForm from './ReportForm.vue';
import print from 'vue-print-nb'
import {getLastPathSegment} from "@/utils/ruoyi";
import { getLastPathSegment } from "@/utils/ruoyi";
import FilePreview from '@/components/FilePreview/index.vue';
import { file } from 'jszip';
export default {
name: "Report",
@ -154,6 +132,7 @@ export default {
},
components: {
ReportForm,
FilePreview
},
data() {
return {
@ -250,16 +229,16 @@ export default {
/** 搜索按钮操作 */
handleQuery() {
const reportTime = this.queryParams.reportTime;
this.queryParams = {
this.queryParams = {
pageNo: 1,
pageSize: 10,
reportTopic: null,
reportTime: reportTime,
createTime: [],
userId: null,
userName: null,
servicePackageId: this.$route.query.servicePackageId,
dictType: this.$route.query.dictType,
pageSize: 10,
reportTopic: null,
reportTime: reportTime,
createTime: [],
userId: null,
userName: null,
servicePackageId: this.$route.query.servicePackageId,
dictType: this.$route.query.dictType,
}
this.queryParams.pageNo = 1;
this.getList();
@ -311,13 +290,26 @@ export default {
}
//
this.currentFileList = filePath.split(',').filter(item => item.trim());
this.fileDialogVisible = true;
this.currentFileList = filePath.split(',')
.filter(item => item.trim()) //
.map(item => {
const parts = item.trim().split('/'); //
const name = parts[parts.length - 1]; //
return {
url: item.trim(),
name: name
};
});
// this.fileDialogVisible = true;
// this.$refs.filePreview.openPreview(this.currentFileList[0],this.currentFileList)
this.$refs.filePreview.openPreview(this.currentFileList[0], this.currentFileList)
//
if (this.currentFileList.length > 0) {
this.previewFile(this.currentFileList[0]);
}
// if (this.currentFileList.length > 0) {
// this.previewFile(this.currentFileList[0]);
// }
},
// URLAPI
@ -369,7 +361,7 @@ export default {
},
//
getRowClassName({row}) {
getRowClassName({ row }) {
return row === this.currentFileUrl ? 'highlight-row' : '';
},
@ -422,5 +414,4 @@ export default {
.highlight-row {
background-color: #f0f7ff;
}
</style>

View File

@ -2,7 +2,7 @@
<div>
<div style="display: flex; align-items: center;">
<el-select v-model="carSelected" clearable style="width: 200px;">
<el-option v-for="car in carList" :key="car.id" :label="car.licenseNumber" :value="car.id"/>
<el-option v-for="car in carList" :key="car.id" :label="car.licenseNumber" :value="car.id" />
</el-select>
<el-button type="primary" size="small" @click="addNewCar" style="margin-left: 8px;">
新增车辆
@ -14,7 +14,7 @@
<script>
import {remindCarMainPage} from "@/api/base/carmain";
import { remindCarMainPage } from "@/api/base/carmain";
import AddCarForm from "./AddCarForm.vue";
export default {
@ -33,7 +33,7 @@ export default {
type: Object,
required: true
},
inList:{
inList: {
type: Object,
default: null,
required: false
@ -53,16 +53,19 @@ export default {
value(val) {
this.carSelected = val ? val.id : null;
},
cusName(val, old) {
if (val !== old) {
// this.carSelected = null
this.getCarList()
}
cusName: {
handler(val, old) {
if (val !== old) {
// this.carSelected = null
this.getCarList()
}
},
immediate: true
},
inList(val){
if (val){
inList(val) {
if (val) {
const flag = this.carList.findIndex(item => item.id === val.id)
if (flag > 0){
if (flag > 0) {
this.carList.splice(flag, 1)
}
this.carList.unshift(val)
@ -108,6 +111,4 @@ export default {
}
</script>
<style scoped lang="scss">
</style>
<style scoped lang="scss"></style>

View File

@ -483,7 +483,7 @@ export default {
soiType: this.type ? '02' : "04",
goodsId: item.waresId,
goodsCount: item.waresCount,
goodsPrice: item.salePrice
goodsPrice: item.salePrice,
}
})]
this.formData.ids = this.allSelectRows.map(item => item.id)

View File

@ -413,7 +413,7 @@
<!-- <th>单位</th> -->
<th style="width: 9%">数量</th>
<th style="width: 9%">单价</th>
<th style="width: 9%">折扣</th>
<!-- <th style="width: 9%">折扣</th> -->
<!-- <th v-if="checkPermi(['repair:tick:profit'])">毛利</th>
<th v-if="checkPermi(['repair:tick:profit'])">毛利率</th> -->
<th style="width: 8%">金额</th>
@ -438,7 +438,7 @@
</td> -->
<td>{{ item.itemCount }}</td>
<td>{{ item.itemPrice }}</td>
<td>{{ item.itemDiscount }}</td>
<!-- <td>{{ item.itemDiscount }}</td> -->
<!-- <td v-if="checkPermi(['repair:tick:profit'])">
{{ item.itemProfit }}
</td>
@ -479,13 +479,13 @@
<th style="width: 12%">单位</th>
<th style="width: 12%">数量</th>
<th style="width: 12%">单价</th>
<th style="width: 12%">折扣</th>
<th v-if="checkPermi(['repair:tick:profit'])">毛利</th>
<th v-if="checkPermi(['repair:tick:profit'])">毛利率</th>
<!-- <th style="width: 12%">折扣</th> -->
<!-- <th v-if="checkPermi(['repair:tick:profit'])">毛利</th> -->
<!-- <th v-if="checkPermi(['repair:tick:profit'])">毛利率</th> -->
<th style="width: 12%">金额</th>
<th style="width: 12%">施工人员</th>
<th style="width: 12%">服务顾问</th>
<th>备注</th>
<!-- <th>备注</th> -->
</tr>
</thead>
<tbody>
@ -501,8 +501,8 @@
</td>
<td>{{ item.itemCount }}</td>
<td>{{ item.itemPrice }}</td>
<td>{{ item.itemDiscount }}</td>
<td v-if="checkPermi(['repair:tick:profit'])">
<!-- <td>{{ item.itemDiscount }}</td> -->
<!-- <td v-if="checkPermi(['repair:tick:profit'])">
{{ item.itemProfit }}
</td>
<td v-if="checkPermi(['repair:tick:profit'])">
@ -511,11 +511,11 @@
? (item.itemProfitRate * 100).toFixed(2) + "%"
: ""
}}
</td>
</td> -->
<td style="width: 12%">{{ item.itemMoney }}</td>
<td style="width: 12%">{{ item.repairNames }}</td>
<td style="width: 12%">{{ item.saleName }}</td>
<td>{{ item.remark }}</td>
<!-- <td>{{ item.remark }}</td> -->
</tr>
</tbody>
</table>
@ -542,13 +542,13 @@
<th>单位</th>
<th>数量</th>
<th>单价</th>
<th>折扣</th>
<th v-if="checkPermi(['repair:tick:profit'])">毛利</th>
<th v-if="checkPermi(['repair:tick:profit'])">毛利率</th>
<!-- <th>折扣</th> -->
<!-- <th v-if="checkPermi(['repair:tick:profit'])">毛利</th>
<th v-if="checkPermi(['repair:tick:profit'])">毛利率</th> -->
<th style="width: 12%">金额</th>
<th style="width: 12%">施工人员</th>
<th style="width: 12%">服务顾问</th>
<th>备注</th>
<!-- <th>备注</th> -->
</tr>
</thead>
<tbody>
@ -564,8 +564,8 @@
</td>
<td>{{ item.itemCount }}</td>
<td>{{ item.itemPrice }}</td>
<td>{{ item.itemDiscount }}</td>
<td v-if="checkPermi(['repair:tick:profit'])">
<!-- <td>{{ item.itemDiscount }}</td> -->
<!-- <td v-if="checkPermi(['repair:tick:profit'])">
{{ item.itemProfit }}
</td>
<td v-if="checkPermi(['repair:tick:profit'])">
@ -574,11 +574,11 @@
? (item.itemProfitRate * 100).toFixed(2) + "%"
: ""
}}
</td>
</td> -->
<td style="width: 12%">{{ item.itemMoney }}</td>
<td style="width: 12%">{{ item.repairNames }}</td>
<td style="width: 12%">{{ item.saleName }}</td>
<td>{{ item.remark }}</td>
<!-- <td>{{ item.remark }}</td> -->
</tr>
</tbody>
</table>
@ -599,14 +599,14 @@
<tr>
<td><strong>总数量</strong></td>
<td>{{ totalCount }}</td>
<td><strong>成本</strong></td>
<td>{{ otherInfo.cost }}</td>
<!-- <td><strong>成本</strong></td>
<td>{{ otherInfo.cost }}</td> -->
<td><strong>总金额</strong></td>
<td>{{ totalMoney }}</td>
</tr>
</tbody>
</table>
<div v-if="checkPermi(['repair:tick:profit'])">
<!-- <div v-if="checkPermi(['repair:tick:profit'])">
<table
class="print-table"
border="1"
@ -669,7 +669,7 @@
</tr>
</tbody>
</table>
</div>
</div> -->
</div>
</template>
</PrintButton>