This commit is contained in:
2026-10-08 18:19:39 +08:00
parent 25b8d0104f
commit 75527ae81d
425 changed files with 53925 additions and 2645 deletions
+135
View File
@@ -0,0 +1,135 @@
<template>
<div>
<el-dialog title="报价明细" :visible.sync="dialogVisible" width="60%">
<el-table :data="list" style="width: 100%">
<el-table-column prop="subjectName" label="报价方"/>
<el-table-column prop="subjectMobile" label="联系方式"/>
<el-table-column prop="totalPrice" label="金额"/>
<el-table-column label="附件">
<template v-slot="{ row }">
<a
style="margin-right: 10px"
v-for="(item, index) in row.files"
:key="index"
href="javascript:;"
@click="previewFile(item)"
>预览: 文件{{ index + 1 }}</a>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注"/>
<el-table-column prop="_add_time_str" label="报价时间"/>
</el-table>
</el-dialog>
<el-dialog title="图片预览" :visible.sync="showImagePreview" width="80%" append-to-body>
<img v-if="previewImageUrl" class="preview-image" :src="previewImageUrl" alt="附件预览"/>
</el-dialog>
<el-dialog title="PDF预览" :visible.sync="showPdfPreview" width="80%" append-to-body @closed="revokePdfPreviewUrl">
<iframe v-if="pdfPreviewUrl" class="pdf-preview-frame" :src="pdfPreviewUrl"></iframe>
</el-dialog>
</div>
</template>
<script>
export default {
name: "EnquiryQuoteList",
data() {
return {
dialogVisible: false,
list: [],
showImagePreview: false,
previewImageUrl: '',
showPdfPreview: false,
pdfPreviewUrl: '',
pdfObjectUrl: '',
}
},
beforeDestroy() {
this.revokePdfPreviewUrl()
},
methods: {
open(sheetId){
this.getList(sheetId)
},
async getList(sheetId){
const {rows} = await vk.callFunction({
url: 'admin/enquiry/quote/kh/getList',
data: {
sheetId
}
})
this.dialogVisible = true
this.list = rows
},
getFileExt(url = "") {
const cleanUrl = String(url).split("?")[0].split("#")[0]
const match = cleanUrl.match(/\.([a-z0-9]+)$/i)
return match ? match[1].toLowerCase() : ""
},
isImageFile(url) {
return ["png", "jpg", "jpeg", "gif", "webp", "bmp", "svg"].includes(this.getFileExt(url))
},
isPdfFile(url) {
return this.getFileExt(url) === "pdf"
},
isOfficeFile(url) {
return ["doc", "docx", "xls", "xlsx", "ppt", "pptx"].includes(this.getFileExt(url))
},
getOfficePreviewUrl(url) {
return `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(url)}`
},
revokePdfPreviewUrl() {
if (this.pdfObjectUrl) {
URL.revokeObjectURL(this.pdfObjectUrl)
this.pdfObjectUrl = ''
}
this.pdfPreviewUrl = ''
},
async previewPdfFile(url) {
this.revokePdfPreviewUrl()
try {
const response = await fetch(url)
if (!response.ok) throw new Error('PDF加载失败')
const blob = await response.blob()
this.pdfObjectUrl = URL.createObjectURL(new Blob([blob], {type: 'application/pdf'}))
this.pdfPreviewUrl = this.pdfObjectUrl
} catch (e) {
this.pdfPreviewUrl = `https://mozilla.github.io/pdf.js/web/viewer.html?file=${encodeURIComponent(url)}`
}
this.showPdfPreview = true
},
previewFile(url) {
if (!url) return
if (this.isImageFile(url)) {
this.previewImageUrl = url
this.showImagePreview = true
return
}
if (this.isPdfFile(url)) {
this.previewPdfFile(url)
return
}
if (this.isOfficeFile(url)) {
window.open(this.getOfficePreviewUrl(url), "_blank")
return
}
window.open(url, "_blank")
}
}
}
</script>
<style scoped>
.preview-image {
display: block;
max-width: 100%;
max-height: 75vh;
margin: 0 auto;
}
.pdf-preview-frame {
display: block;
width: 100%;
height: 75vh;
border: 0;
}
</style>
+140
View File
@@ -0,0 +1,140 @@
<template>
<div>
<el-dialog title="报价明细" :visible.sync="dialogVisible" width="60%">
<el-table :data="list" style="width: 100%">
<el-table-column prop="subjectName" label="报价方"/>
<el-table-column label="联系方式">
<template #default="{ row }">
<span v-if="row.user.accountType === 2">{{ row.user.company.mobile }}</span>
<span v-else>{{ row.user.person.mobile }}</span>
</template>
</el-table-column>
<el-table-column prop="totalPrice" label="金额"/>
<el-table-column label="附件">
<template #default="{ row }">
<a
href="javascript:;"
style="margin-right: 10px"
v-for="(item, index) in row.files"
:key="index"
@click="previewFile(item)"
>附件:{{ index + 1 }}</a>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注"/>
<el-table-column prop="_add_time_str" label="报价时间"/>
</el-table>
</el-dialog>
<el-dialog title="图片预览" :visible.sync="showImagePreview" width="80%" append-to-body>
<img v-if="previewImageUrl" class="preview-image" :src="previewImageUrl" alt="附件预览"/>
</el-dialog>
<el-dialog title="PDF预览" :visible.sync="showPdfPreview" width="80%" append-to-body @closed="revokePdfPreviewUrl">
<iframe v-if="pdfPreviewUrl" class="pdf-preview-frame" :src="pdfPreviewUrl"></iframe>
</el-dialog>
</div>
</template>
<script>
export default {
name: "OldQuoteList",
data() {
return {
dialogVisible: false,
list: [],
showImagePreview: false,
previewImageUrl: '',
showPdfPreview: false,
pdfPreviewUrl: '',
pdfObjectUrl: '',
}
},
beforeDestroy() {
this.revokePdfPreviewUrl()
},
methods: {
open(sheetId) {
this.getList(sheetId)
},
async getList(sheetId) {
const {rows} = await vk.callFunction({
url: 'admin/old/quote/kh/getList',
data: {
sheetId
}
})
this.dialogVisible = true
this.list = rows
},
getFileExt(url = "") {
const cleanUrl = String(url).split("?")[0].split("#")[0]
const match = cleanUrl.match(/\.([a-z0-9]+)$/i)
return match ? match[1].toLowerCase() : ""
},
isImageFile(url) {
return ["png", "jpg", "jpeg", "gif", "webp", "bmp", "svg"].includes(this.getFileExt(url))
},
isPdfFile(url) {
return this.getFileExt(url) === "pdf"
},
isOfficeFile(url) {
return ["doc", "docx", "xls", "xlsx", "ppt", "pptx"].includes(this.getFileExt(url))
},
getOfficePreviewUrl(url) {
return `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(url)}`
},
revokePdfPreviewUrl() {
if (this.pdfObjectUrl) {
URL.revokeObjectURL(this.pdfObjectUrl)
this.pdfObjectUrl = ''
}
this.pdfPreviewUrl = ''
},
async previewPdfFile(url) {
this.revokePdfPreviewUrl()
try {
const response = await fetch(url)
if (!response.ok) throw new Error('PDF加载失败')
const blob = await response.blob()
this.pdfObjectUrl = URL.createObjectURL(new Blob([blob], {type: 'application/pdf'}))
this.pdfPreviewUrl = this.pdfObjectUrl
} catch (e) {
this.pdfPreviewUrl = `https://mozilla.github.io/pdf.js/web/viewer.html?file=${encodeURIComponent(url)}`
}
this.showPdfPreview = true
},
previewFile(url) {
if (!url) return
if (this.isImageFile(url)) {
this.previewImageUrl = url
this.showImagePreview = true
return
}
if (this.isPdfFile(url)) {
this.previewPdfFile(url)
return
}
if (this.isOfficeFile(url)) {
window.open(this.getOfficePreviewUrl(url), "_blank")
return
}
window.open(url, "_blank")
}
}
}
</script>
<style scoped>
.preview-image {
display: block;
max-width: 100%;
max-height: 75vh;
margin: 0 auto;
}
.pdf-preview-frame {
display: block;
width: 100%;
height: 75vh;
border: 0;
}
</style>
+80
View File
@@ -0,0 +1,80 @@
<template>
<div>
<el-descriptions border :column="2">
<el-descriptions-item label="商品列表">
<div v-for="(item, index) in info.goods" :key="index" style="
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;">
<p>商品名称: {{ item.goodsName }}</p>
<p v-if="info.type === 0 && formatSku(item.sku)">规格: {{ formatSku(item.sku) }}</p>
<p>数量: x{{ item.num }}</p>
<p>单价: {{ item.goodsPrice }}元</p>
<p v-if="info.type === 0">所属公司: {{ item.company.company.companyName }}</p>
<el-divider v-if="index < info.goods.length - 1"/>
</div>
</el-descriptions-item>
<el-descriptions-item label="用户信息">
<p>用户名: {{ info.user.nickname }}</p>
<p>手机号: {{ info.user.mobile }}</p>
</el-descriptions-item>
<el-descriptions-item label="买家信息">
<p>收件人: {{ info.name }}</p>
<p>收件人联系方式: {{ info.phone }}</p>
<p>收件地址: {{ info.addressRegion.province.name }}{{
info.addressRegion.city.name
}}{{ info.addressRegion.area.name }}{{ info.addressDetail }}</p>
</el-descriptions-item>
<el-descriptions-item label="物流信息">
<p>物流公司: {{ info.expressName }}</p>
<p>物流单号: {{ info.expressNo }}</p>
<p>备注: {{ info.remark }}</p>
<el-image v-for="(item, index) in info.expressPhoto" :key="index" :src="item"
class="mr-10 mb-10"
:preview-src-list="info.expressPhoto" style="width: 100px;height: 100px"/>
</el-descriptions-item>
<template v-if="info.orderStatus >= 5">
<el-descriptions-item label="退款信息">
<p>退款原因: {{ info.refundReason }}</p>
<div>
<span>退款附件: </span>
<a style="margin-right: 1rem" v-for="(file, fileIndex) in info.refundPhotos" :key="fileIndex" :href="file"
target="_blank">预览:文件{{ fileIndex + 1 }}</a>
</div>
</el-descriptions-item>
</template>
</el-descriptions>
<div style="margin-top: 2rem; text-align: center">
<el-button plain @click.native="cancel">关闭</el-button>
</div>
</div>
</template>
<script>
export default {
name: "OrderInfo",
props: {
info: {
type: Object
}
},
data() {
return {}
},
methods: {
formatSku(sku) {
if (!sku) return ''
if (typeof sku === 'string') return sku
return sku.label || sku.name || sku.title || sku.specName || ''
},
cancel() {
this.$emit('close')
},
},
mounted() {
// this.getList()
}
}
</script>
+82
View File
@@ -0,0 +1,82 @@
<template>
<el-dialog title="支付明细" :visible.sync="dialogVisible" width="60%">
<view v-for="(item, index) in payList" :key="index" class="py-20 border-bottom">
<el-descriptions :title="item.type" :column="2" border :labelStyle="{width: '120px'}">
<template slot="extra">
<div class="flex justify-start items-center">
<template v-if="!item.buyerRefuse">
<el-button plain type="primary" size="mini" @click="showPay(item)"
v-if="item.status === 0 && item.isBuyer && !item.hasPaid">上传支付凭证
</el-button>
<el-button type="primary" size="mini" class="mx-20" @click="confirmPay(item)"
v-if="item.hasPaid && item.isSeller && !item.sellerConfirm">
确认收款
</el-button>
<el-button plain type="primary" size="mini" class="mx-20" @click="paidRefuse(item)"
v-if="item.isBuyer && item.status === 0 && !item.paidVoucher">
驳回
</el-button>
</template>
</div>
</template>
<el-descriptions-item label="支付金额">{{ item.amount }}</el-descriptions-item>
<el-descriptions-item label="支付凭证">
<template v-if="!item.buyerRefuse">
<span v-if="item.isSeller && !item.hasPaid">待买方支付</span>
<view v-else-if="item.paidVoucher">
<el-image :src="item.paidVoucher[0]" style="width: 80px; height: 80px" fit="cover"
:preview-src-list="item.paidVoucher"/>
</view>
<view v-else-if="!item.paidVoucher">
<span>未上传凭证</span>
</view>
</template>
<span v-else class="text-main">买家已拒绝: {{ item.refuseReason }}</span>
</el-descriptions-item>
<el-descriptions-item label="交货凭证">
<el-image v-for="(photo, photoIndex) in item.expressPhoto" :key="photoIndex" :src="photo"
style="width: 80px; height: 80px" fit="cover"
:preview-src-list="item.expressPhoto"/>
</el-descriptions-item>
<el-descriptions-item label="备注">
<text>{{ item.remark ? item.remark : '无' }}</text>
</el-descriptions-item>
<el-descriptions-item label="买家备注">
<text>{{ item.buyerRemark ? item.buyerRemark : '无' }}</text>
</el-descriptions-item>
<el-descriptions-item label="图片">
<template v-if="item.photos && item.photos.length > 0">
<el-image v-for="(photo, photoIndex) in item.photos" :key="photoIndex" :src="photo"
style="width: 80px; height: 80px" fit="cover"
:preview-src-list="item.photos"/>
</template>
<span v-else>无</span>
</el-descriptions-item>
<el-descriptions-item label="状态">
<span v-if="!item.hasPaid && !item.buyerRefuse">待上传凭证</span>
<span v-if="!item.sellerConfirm && item.hasPaid">待确认收款</span>
<span v-if="item.sellerConfirm && item.hasPaid">已完成</span>
</el-descriptions-item>
</el-descriptions>
</view>
</el-dialog>
</template>
<script>
export default {
name: "PayList",
data() {
return {
dialogVisible: false,
payList: [],
}
},
methods: {
open(payList) {
this.payList = payList
this.dialogVisible = true
},
}
}
</script>
+146
View File
@@ -0,0 +1,146 @@
<template>
<div>
<el-dialog title="报价列表" :visible.sync="dialogVisible" width="60%">
<el-table :data="list" style="width: 100%">
<el-table-column label="报价方">
<template #default="{ row }">
<span v-if="row.user.accountType === 2">{{ row.user.company.companyName }}</span>
<span v-else>{{ row.user.person.personName }}</span>
</template>
</el-table-column>
<el-table-column label="联系方式">
<template #default="{ row }">
<span v-if="row.user.accountType === 2">{{ row.user.company.mobile }}</span>
<span v-else>{{ row.user.person.mobile }}</span>
</template>
</el-table-column>
<el-table-column prop="totalPrice" label="金额"/>
<el-table-column label="附件">
<template #default="{ row }">
<a
href="javascript:;"
style="margin-right: 10px"
v-for="(item, index) in row.files"
:key="index"
@click="previewFile(item)"
>附件:{{ index + 1 }}</a>
</template>
</el-table-column>
<el-table-column prop="remark" label="报价单详情"/>
<el-table-column prop="supplierExt" label="合同补充条款"/>
<el-table-column prop="_add_time_str" label="报价时间"/>
</el-table>
</el-dialog>
<el-dialog title="图片预览" :visible.sync="showImagePreview" width="80%" append-to-body>
<img v-if="previewImageUrl" class="preview-image" :src="previewImageUrl" alt="附件预览"/>
</el-dialog>
<el-dialog title="PDF预览" :visible.sync="showPdfPreview" width="80%" append-to-body @closed="revokePdfPreviewUrl">
<iframe v-if="pdfPreviewUrl" class="pdf-preview-frame" :src="pdfPreviewUrl"></iframe>
</el-dialog>
</div>
</template>
<script>
export default {
name: "ProcessQuoteList",
data() {
return {
dialogVisible: false,
list: [],
showImagePreview: false,
previewImageUrl: '',
showPdfPreview: false,
pdfPreviewUrl: '',
pdfObjectUrl: '',
}
},
beforeDestroy() {
this.revokePdfPreviewUrl()
},
methods: {
open(sheetId) {
this.getList(sheetId)
},
async getList(sheetId) {
const {rows} = await vk.callFunction({
url: 'admin/process/quote/kh/getList',
data: {
sheetId
}
})
this.dialogVisible = true
this.list = rows
},
getFileExt(url = "") {
const cleanUrl = String(url).split("?")[0].split("#")[0]
const match = cleanUrl.match(/\.([a-z0-9]+)$/i)
return match ? match[1].toLowerCase() : ""
},
isImageFile(url) {
return ["png", "jpg", "jpeg", "gif", "webp", "bmp", "svg"].includes(this.getFileExt(url))
},
isPdfFile(url) {
return this.getFileExt(url) === "pdf"
},
isOfficeFile(url) {
return ["doc", "docx", "xls", "xlsx", "ppt", "pptx"].includes(this.getFileExt(url))
},
getOfficePreviewUrl(url) {
return `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(url)}`
},
revokePdfPreviewUrl() {
if (this.pdfObjectUrl) {
URL.revokeObjectURL(this.pdfObjectUrl)
this.pdfObjectUrl = ''
}
this.pdfPreviewUrl = ''
},
async previewPdfFile(url) {
this.revokePdfPreviewUrl()
try {
const response = await fetch(url)
if (!response.ok) throw new Error('PDF加载失败')
const blob = await response.blob()
this.pdfObjectUrl = URL.createObjectURL(new Blob([blob], {type: 'application/pdf'}))
this.pdfPreviewUrl = this.pdfObjectUrl
} catch (e) {
this.pdfPreviewUrl = `https://mozilla.github.io/pdf.js/web/viewer.html?file=${encodeURIComponent(url)}`
}
this.showPdfPreview = true
},
previewFile(url) {
if (!url) return
if (this.isImageFile(url)) {
this.previewImageUrl = url
this.showImagePreview = true
return
}
if (this.isPdfFile(url)) {
this.previewPdfFile(url)
return
}
if (this.isOfficeFile(url)) {
window.open(this.getOfficePreviewUrl(url), "_blank")
return
}
window.open(url, "_blank")
}
}
}
</script>
<style scoped>
.preview-image {
display: block;
max-width: 100%;
max-height: 75vh;
margin: 0 auto;
}
.pdf-preview-frame {
display: block;
width: 100%;
height: 75vh;
border: 0;
}
</style>
+161
View File
@@ -0,0 +1,161 @@
<template>
<div>
<el-descriptions border :column="2" v-if="info">
<el-descriptions-item label="服务">
<div v-for="(item, index) in goods" :key="index">
<p>{{ item.goodsName }}</p>
<template v-if="orderInfo.subType === 2 && item.amountItem">
<p>项基础收费: {{ item.amountItem.amount }}元</p>
<p v-if="item.costNum">清单单品项数: {{ item.costNum }}</p>
<p>项数加价: {{ item.amountItem.addAmount }}元</p>
<p>建议收费: {{ item.amountItem.amount + (item.costNum * item.amountItem.addAmount) }}元</p>
</template>
</div>
</el-descriptions-item>
<el-descriptions-item label="考察对象" v-if="info.type === 0">
<div v-for="(item, index) in info.contentList" :key="index">
<span>类型:{{ item.type }},</span>
<span>{{ item.name }}</span>
<template v-if="item.type && item.type === '个人'">
<span>({{ item.code }})</span>
<span>--{{ item.addressRegion.province.name }}{{
item.addressRegion.city.name
}}{{ item.addressRegion.area.name }}{{ item.address }}</span>
</template>
</div>
</el-descriptions-item>
<el-descriptions-item label="考察产品" v-else>
<p style="margin-bottom: .5rem" v-for="(item, index) in info.contentList" :key="index">{{
item.name
}}--{{ item.addressRegion.province.name }}{{
item.addressRegion.city.name
}}{{ item.addressRegion.area.name }}{{ item.address }}</p>
</el-descriptions-item>
<el-descriptions-item label="文档">
<div v-for="(item, index) in info.contentList" :key="index">
<template v-if="item.files">
<a v-for="(file, fileIndex) in item.files" :key="fileIndex" :href="file"
target="_blank">预览:文件{{ fileIndex + 1 }}</a>
</template>
</div>
</el-descriptions-item>
<el-descriptions-item label="接收文件电子邮箱">
<span>{{ info.email }}</span>
</el-descriptions-item>
<el-descriptions-item label="接收文件微信">
<span>{{ info.wechat }}</span>
</el-descriptions-item>
<el-descriptions-item label="接收文件寄件地址">
<span v-if="info.receiveAddressRegion.province">{{
info.receiveAddressRegion.province.name
}}{{ info.receiveAddressRegion.city.name }}{{
info.receiveAddressRegion.area.name
}}{{ info.receiveAddress }}</span>
</el-descriptions-item>
<el-descriptions-item label="申请人">
<span>{{ info.requestName }}</span>
</el-descriptions-item>
<el-descriptions-item label="业务联系人">
<span>{{ info.contactName }}</span>
</el-descriptions-item>
<el-descriptions-item label="业务联系方式">
<span>{{ info.contact }}</span>
</el-descriptions-item>
<el-descriptions-item label="用户备注">
<span>{{ info.remark ? info.remark : '' }}</span>
</el-descriptions-item>
<el-descriptions-item label="接单公司" v-if="info.companyId">
<span>{{ info.company.company.companyName }}</span>
</el-descriptions-item>
<el-descriptions-item label="结果文件" v-if="orderInfo && orderInfo.resultFiles">
<div v-for="(item, index) in orderInfo.resultFiles" :key="index">
<a :href="item"
target="_blank">预览:文件{{ index + 1 }}</a>
</div>
</el-descriptions-item>
<el-descriptions-item label="发送途径" v-if="orderInfo && orderInfo.sendMethod"><span>{{
orderInfo.sendMethod
}}</span>
</el-descriptions-item>
</el-descriptions>
<template v-if="info && !info.companyId && isSet">
<p style="margin-top: 2rem">接单公司</p>
<el-row :gutter="10">
<el-col :span="6">
<el-select v-model="companyId" placeholder="请选择接单公司" style="width: 100%">
<el-option
v-for="(item, index) in companyList"
:disabled="item._id === info.uid"
:key="item.value"
:label="item.company.companyName"
:value="item._id">
</el-option>
</el-select>
</el-col>
<el-col :span="2">
<el-button type="primary" @click.native="setCompany" :disabled="!companyId">确定</el-button>
</el-col>
</el-row>
</template>
</div>
</template>
<script>
export default {
name: "selfProductInfo",
props: {
orderInfo: null,
orderId: null,
goods: null,
isSet: false,
},
data() {
return {
info: null,
companyId: null,
companyList: [],
}
},
methods: {
async getInfo() {
const {data} = await vk.callFunction({
url: 'admin/selfProduct/order/sys/getDetail',
data: {
orderId: this.orderId
}
})
this.info = data
},
async getCompanyList() {
const data = {type: 2, pageSize: 500}
if (this.info.type === 0) data.isCompanyQuote = true
else if (this.info.type === 1) data.isProductQuote = true
else if (this.info.type === 2) data.isCostQuote = true
const {rows} = await vk.callFunction({
url: 'admin/system/user/sys/getList',
data
})
this.companyList = rows.filter(item => item.company && item.company.companyName !== '' && item.company.companyName)
},
async setCompany() {
if (!this.companyId) return this.$message.error('请选择接单公司')
await vk.callFunction({
url: 'admin/selfProduct/order/sys/setCompany',
data: {
orderId: this.info.orderId,
companyId: this.companyId
}
})
this.close()
},
close() {
this.$emit('close')
}
},
async mounted() {
console.log(this.orderInfo)
await this.getInfo()
if (this.isSet) await this.getCompanyList()
}
}
</script>
+91
View File
@@ -0,0 +1,91 @@
<template>
<el-form ref="form" label-width="80px">
<template>
<el-form-item label="订单号">
{{ info.orderNo }}
</el-form-item>
<el-form-item label="收件人">
{{ info.name }}({{ info.phone }})
</el-form-item>
<el-form-item label="收货地址" v-if="info.address.area">
{{ info.address.province.name }} {{ info.address.city.name }} {{ info.address.area.name }} {{
info.address.addressDetail
}}
</el-form-item>
</template>
<el-form-item label="物流公司" required>
<el-input v-model="expressName" placeholder="请输入物流公司"/>
</el-form-item>
<el-form-item label="物流单号" required>
<el-input v-model="expressNo" placeholder="请输入物流单号"/>
</el-form-item>
<el-form-item label="发货单" required>
<vk-data-upload v-model="expressPhoto"></vk-data-upload>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="remark" placeholder="请输入备注"/>
</el-form-item>
<div class="mt-20 flex justify-center items-center text-center">
<el-button type="primary" size="small" plain @click.native="cancel">取消</el-button>
<el-button type="primary" size="small" @click.native="confirm">确定</el-button>
</div>
</el-form>
</template>
<script>
export default {
name: "setExpress",
props: {
info: Object
},
data() {
return {
expressName: null,
expressNo: null,
remark: null,
expressPhoto: [],
}
},
methods: {
close() {
this.$emit('close')
},
cancel() {
this.expressName = null
this.expressNo = null
this.remark = null
this.expressPhoto = []
this.close()
},
async confirm() {
if (!this.expressName) return this.$message({
type: 'error',
message: '请填写物流公司'
})
if (!this.expressNo) return this.$message({
type: 'error',
message: '请填写物流单号'
})
if (this.expressPhoto.length === 0) return this.$message({
type: 'error',
message: '请上传发货单'
})
await vk.callFunction({
url: 'admin/order/sys/setExpress',
data: {
id: this.info._id,
expressName: this.expressName,
expressNo: this.expressNo,
remark: this.remark,
expressPhoto: this.expressPhoto
}
})
this.$emit('close')
this.$message({
type: 'success',
message: '发货成功'
})
}
}
}
</script>
+68
View File
@@ -0,0 +1,68 @@
<template>
<el-form ref="form" label-width="80px">
<template>
<el-form-item label="选择服务公司">
{{ info.orderNo }}
</el-form-item>
</template>
<div class="mt-20 flex justify-center items-center text-center">
<el-button type="primary" size="small" plain @click.native="cancel">取消</el-button>
<el-button type="primary" size="small" @click.native="confirm">确定</el-button>
</div>
</el-form>
</template>
<script>
export default {
name: "setSelfSupport",
props: {
info: Object
},
data() {
return {
sheet: null,
expressNo: null,
remark: null,
expressPhoto: [],
}
},
methods: {
async getInfo() {
const {data} = await vk.callFunction({
url: 'admin/selfProduct/order/sys/getDetail',
data: {
orderId: this.info.orderId
}
})
this.sheet = data
},
close() {
this.$emit('close')
},
cancel() {
this.close()
},
async confirm() {
await vk.callFunction({
url: 'admin/order/sys/setExpress',
data: {
id: this.info._id,
expressName: this.expressName,
expressNo: this.expressNo,
remark: this.remark,
expressPhoto: this.expressPhoto
}
})
this.$emit('close')
this.$message({
type: 'success',
message: '发货成功'
})
}
},
mounted() {
this.getInfo()
}
}
</script>
+836
View File
@@ -0,0 +1,836 @@
<template>
<view class="page-body">
<!-- 页面内容开始 -->
<!-- 表格搜索组件开始 -->
<vk-data-table-query v-model="queryForm1.formData" :columns="queryForm1.columns"
@search="search"></vk-data-table-query>
<!-- 表格搜索组件结束 -->
<!-- 自定义按钮区域开始 -->
<view>
<el-row>
</el-row>
</view>
<!-- 自定义按钮区域结束 -->
<!-- 表格组件开始 -->
<vk-data-table ref="table1" :action="table1.action" :columns="table1.columns" :query-form-param="queryForm1"
:pagination="true" @current-change="currentChange"
>
<template v-slot:action="{ row, column, index }">
<el-button size="mini" @click.native="doShowInfo(row)">详情</el-button>
<el-button size="mini" @click.native="showQuoteList(row)" v-if="row.quoteNum > 0">报价列表</el-button>
<el-button size="mini" @click.native="showPayList(row)" v-if="row.payList">支付明细</el-button>
</template>
<template v-slot:isShow="{ row, column, index }">
<el-switch v-if="row.status === 0" v-model="row.isShow" size="mini"
@change="changeField(row._id, 'isShow', $event)"
:active-value="1"
:inactive-value="0"/>
<span v-else></span>
</template>
<template v-slot:quoteAmount="{ row, column, index }">
<el-input-number v-model="row.quoteAmount" @change="changeQuoteAmount($event, row._id)"/>
</template>
<template v-slot:notaryServiceRate="{ row, column, index }">
<view v-if="row.tradeMethod === 1" class="flex justify-start items-center">
<el-input-number style="width: 150px"
v-model="row.notaryServiceRate"
:min="0"
:precision="3"
:step="0.1"
:controls="false"
@change="changeNotaryServiceRate($event, row)"
/>
<text class="ml-10">%</text>
</view>
<span v-else></span>
</template>
<template v-slot:orderAmount="{ row, column, index }">
<p v-if="row.order">报价金额: ¥{{ row.order.amount }}</p>
<p v-if="row.payList">实付金额: ¥{{
row.payList.reduce((pre, cur) => (cur.hasPaid && !cur.buyerRefuse && cur.sellerConfirm) ? parseFloat(pre) + parseFloat(cur.amount) : pre, 0)
}}</p>
</template>
</vk-data-table>
<!-- 表格组件结束 -->
<!-- 添加或编辑的弹窗开始 -->
<vk-data-dialog v-model="form1.props.show" :title="form1.props.title" width="60%" mode="form"
:close-on-click-modal="false">
<vk-data-form v-model="form1.data" :rules="form1.props.rules" :action="form1.props.action"
:form-type="form1.props.formType" :columns='form1.props.columns' label-width="120px"
@success="form1.props.show = false;refresh();"></vk-data-form>
</vk-data-dialog>
<!-- 添加或编辑的弹窗结束 -->
<!-- 页面内容结束 -->
<vk-data-dialog
v-model="showInfo"
:title="title"
width="60%"
top="14vh"
center
:close-on-click-modal="true"
>
<vk-data-detail-table
:data="info"
:columns="infoColumns"
size="medium"
label-width="150px"
>
</vk-data-detail-table>
</vk-data-dialog>
<el-dialog title="图片预览" :visible.sync="showImagePreview" width="80%" append-to-body>
<img v-if="previewImageUrl" class="preview-image" :src="previewImageUrl" alt="附件预览"/>
</el-dialog>
<el-dialog title="PDF预览" :visible.sync="showPdfPreview" width="80%" append-to-body @closed="revokePdfPreviewUrl">
<iframe v-if="pdfPreviewUrl" class="pdf-preview-frame" :src="pdfPreviewUrl"></iframe>
</el-dialog>
<EnquiryQuoteList ref="EnquiryQuoteList"/>
<PayList ref="PayList"/>
</view>
</template>
<script>
import EnquiryQuoteList from "./components/EnquiryQuoteList.vue";
var that; // 当前页面对象
var vk = uni.vk; // vk实例
var originalForms = {}; // 表单初始化数据
import provinces from "@/uni_modules/vk-uview-ui/libs/address/provinces.json";
import citys from "@/uni_modules/vk-uview-ui/libs/address/citys.json";
import areas from "@/uni_modules/vk-uview-ui/libs/address/areas.json";
import PayList from "./components/PayList.vue";
import dayjs from "dayjs";
const DEFAULT_NOTARY_SERVICE_RATE = 0.1;
function formatNotaryServiceRate(rate, tradeMethod) {
if (tradeMethod !== 1) return "";
if (rate === undefined || rate === null || rate === "") return `${DEFAULT_NOTARY_SERVICE_RATE}%`;
return typeof rate === "string" && rate.includes("%") ? rate : `${rate}%`;
}
function getEnquiryProductList(row = {}, val = []) {
const otherCate = row.otherCate ? String(row.otherCate).trim() : "";
if (otherCate) {
return [{
goodsName: otherCate,
procureNumber: row.procureNumber,
procureUnit: row.procureUnit
}];
}
return Array.isArray(val) ? val : [];
}
function formatProductNames(val = [], row = {}) {
return getEnquiryProductList(row, val)
.map(item => `${item.goodsName || ""}${item.materialQuality ? `(${item.materialQuality})` : ""}`)
.filter(Boolean)
.join("/");
}
function formatProductAmount(val = [], row = {}) {
return getEnquiryProductList(row, val)
.map(item => `${item.procureNumber ? item.procureNumber : ""}${item.procureUnit ? item.procureUnit : ""}`)
.filter(Boolean)
.join("/");
}
function escapeHtml(value = "") {
return String(value)
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#39;");
}
function formatPreviewLinks(files = []) {
if (!Array.isArray(files)) return "";
return files
.filter(Boolean)
.map((item, itemIndex) => {
const url = encodeURIComponent(item);
const label = escapeHtml(`预览:文件${itemIndex + 1}`);
return `<a href="javascript:;" onclick="window.__previewEnquiryFile && window.__previewEnquiryFile('${url}')">${label}</a> `;
})
.join("");
}
export default {
components: {PayList, EnquiryQuoteList},
data() {
// 页面数据变量
return {
showInfo: false,
info: null,
title: '',
showImagePreview: false,
previewImageUrl: '',
showPdfPreview: false,
pdfPreviewUrl: '',
pdfObjectUrl: '',
provinceData: provinces,
cityData: citys,
areaData: areas,
infoColumns: [
{key: "title", title: "标题", type: "text"},
{
key: "productList", title: "询价内容", type: "html",
formatter: (val = [], row, column, index) => {
let content = ''
getEnquiryProductList(row, val).forEach((item, itemIndex) => {
content += `<p>${item.goodsName} ${item.procureNumber}${item.procureUnit}`
if (item.deliverService) content += ` ,${item.deliverService}`
if (item.pricingForm) content += ` ,${item.pricingForm}`
if (item.loadPaidBy) content += ` ,${item.loadPaidBy}`
content += `</p>`
})
return content
}
},
{
key: "productList", title: "材质", type: "html",
formatter: (val = [], row, column, index) => {
let content = ''
val.forEach(item => {
content += `<div style="border-bottom: 1px solid gray;padding: 1rem 0">${item.goodsName}`
item.model.forEach(model => {
content += `<p>${model.label}: ${model.value}</p> `
})
content += '</div>'
})
return content
},
showRule: formData => {
return formData.fillType === 0
}
},
{
key: "files", title: "附件", type: "html",
formatter: (val = [], row, column, index) => {
return formatPreviewLinks(val)
}
},
{key: "remark", title: "采购商其他要求", type: "text"},
{
key: "multiFiles", title: "采购商其他要求(附件)", type: "html",
formatter: (val = [], row, column, index) => {
return formatPreviewLinks(val)
}
},
{
key: "invoice", title: "是否含税", type: "radio", data: [
{label: "含税", value: true},
{label: "不含税", value: false}
]
},
{
key: "writeInvoiceTime", title: "开票时间", type: "radio", data: [
{label: "付款当月(限20号之前付款,20号之后付款次月开票)", value: 0},
{label: "付款后次月", value: 1},
{label: "付款前", value: 2}
]
},
// {
// key: "invoiceType", title: "发票种类", type: "radio", data: [
// {label: "增值税专用发票13%", value: 0},
// {label: "增值税普通发票", value: 1},
// {label: "普通发票", value: 2}
// ]
// },
{
key: "taxType", title: "纳税人身份", type: "text", showRule: formData => {
return !!formData.invoiceOther
}
},
{
key: "invoiceType", title: "发票种类", type: "text", showRule: formData => {
return !!formData.invoiceOther
}
},
{
key: "taxRate", title: "税率", type: "text", showRule: formData => {
return !!formData.invoiceOther
}
},
{
key: "invoiceOther", title: "手动填写税票要求", type: "text", showRule: formData => {
console.log(formData)
return !!formData.taxType
}
},
{
key: "transportDocuments", title: "随货资料", type: "text", formatter: (val = [], row, column, index) => {
return val.join('、')
}
},
{key: "otherTransportDocuments", title: "运输其他要求", type: "text"},
{
key: "transportLimit", title: "运输限制", type: "radio", data: [
{label: "有", value: true},
{label: "无", value: false}
]
},
{
key: "tradeMethod", title: "交易模式", type: "radio", data: [
{label: "自主交易", value: 0},
{label: "金久信公证", value: 1},
]
},
{
key: "notaryServiceRate",
title: "公证服务费比例",
type: "text",
formatter: (val, row) => {
return formatNotaryServiceRate(val, row.tradeMethod)
},
showRule: formData => {
return formData.tradeMethod === 1
}
},
{
key: "payMethod", title: "付款方式", type: "radio", data: [
{label: "预付", value: 0},
{label: "货到验收后付款", value: 1},
{label: "提货付全款", value: 2},
{label: "信誉采购,货到签单后账期", value: 3},
{label: "其他付款方式", value: 4},
]
},
{
key: "offerType", title: "报价形式", type: "radio", data: [
{label: "整单报价", value: 0},
{label: "可分项报价", value: 1}
]
},
{
key: "answerStartTime", title: "报价时限(开始)", type: "text",
formatter: (val, row, column, index) => {
console.log(val)
return dayjs(val).format("YYYY-MM-DD HH:mm:ss")
}
},
{
key: "answerEndTime", title: "报价时限(结束)", type: "text",
formatter: (val, row, column, index) => {
return dayjs(val).format("YYYY-MM-DD HH:mm:ss")
}
},
{
key: "earnestMoney", title: "交保证金要求", type: "text",
formatter: (val, row, column, index) => {
return val === 'NaN' ? '' : val
}
},
{
key: "signMethod", title: "签约模式", type: "radio", data: [
{label: "线上签约-标准合同", value: 0},
{label: "线下签约", value: 1},
{label: "线上签约-双方协商合同", value: 2},
]
},
{key: "supplementary", title: "采购方补充条款", type: "text"},
{
key: "contract", title: "合同文件", type: "html",
formatter: (val = [], row, column, index) => {
return formatPreviewLinks(row.contract && row.contract.contractBase)
},
showRule: formData => {
return formData.signMethod === 2
}
},
// {
// key: "", title: "项目地址", type: "text"
// },
{
key: "companyName", title: "公司信息", type: "text"
},
{
key: "companyMobile", title: "公司联系方式", type: "text"
},
{
key: "businessName", title: "授权业务咨询人", type: "text"
},
{
key: "businessMobile", title: "业务咨询联系方式", type: "text"
},
{
key: "signName", title: "授权业务签收人", type: "text"
},
{
key: "signMobile", title: "授权业务签收人联系方式", type: "text"
},
{
key: "signIdCard", title: "授权业务签收人身份证号", type: "text"
},
],
// 页面是否请求中或加载中
loading: false,
// init请求返回的数据
data: {},
// 表格相关开始 -----------------------------------------------------------
table1: {
// 表格数据请求地址
action: "admin/enquiry/sys/getList",
// 表格字段显示规则
columns: [
{
key: "productList",
title: "品名/材质",
type: "text",
align: "left",
formatter: (val = [], row, column, index) => {
return formatProductNames(val, row);
}
},
{
key: "enquiryNo",
title: "单号",
type: "text",
align: "left",
width: 200,
},
{
key: "productList",
title: "采购量",
type: "text",
align: "left",
formatter: (val = [], row, column, index) => {
return formatProductAmount(val, row);
}
},
{
key: "addressRegion",
title: "收货地",
type: "text",
align: "left",
width: 200,
formatter: (val = [], row, column, index) => {
let fullAddress = ''
if (val && val.province) fullAddress = `${val.province.name}${val.city.name}${val.area.name}`
if (row.addressDetail) fullAddress = fullAddress + row.addressDetail
return fullAddress;
}
},
{
key: "",
title: "采购企业",
type: "text",
align: "left",
width: 220,
formatter: (val = [], row, column, index) => {
return row.user.accountType === 1 ? row.user.person.personName : row.user.company.companyName;
}
},
{
key: "",
title: "报价情况",
type: "text",
align: "left",
formatter: (val = [], row, column, index) => {
return `${row.quoteNum}家`
}
},
{
key: "status",
title: "状态",
type: "tag",
data: [
{value: 0, label: '待选商', tagType: 'danger'},
{value: 1, label: '已选商', tagType: 'primary'},
{value: 2, label: '已完成', tagType: 'success'},
]
},
{
key: "orderAmount",
title: "订单金额",
type: "html",
width: 160
},
{
key: "notaryServiceRate",
title: "公证服务费比例",
type: "html",
width: 200,
},
{key: "isShow", title: "是否显示", type: "html"},
{key: "quoteAmount", title: "单次报价金额", type: "html", width: 210,},
{
key: "_add_time",
title: "发布时间",
type: "time",
align: "left",
width: 160,
sortable: "custom"
},
{
key: "_add_time_diff",
title: "距离现在",
type: "html",
align: "left",
width: 120,
formatter: (val, row) => vk.pubfn.dateDiff(row._add_time)
},
{key: "action", title: "操作", type: "html", width: 280},
],
// 多选框选中的值
multipleSelection: [],
// 当前高亮的记录
selectItem: ""
},
// 表格相关结束 -----------------------------------------------------------
// 表单相关开始 -----------------------------------------------------------
// 查询表单请求数据
queryForm1: {
// 查询表单数据源,可在此设置默认值
formData: {},
// 查询表单的字段规则 fieldName:指定数据库字段名,不填默认等于key
columns: [
{
key: "title",
title: "标题",
type: "text",
width: 160,
mode: "%%"
},
{
key: "status",
title: "状态",
type: "select",
width: 160,
data: [
{value: 0, label: '未选商'},
{value: 1, label: '已选商'},
{value: 2, label: '已完成'},
]
},
{
key: "signMethod",
title: "签约方式",
type: "select",
data: [
{value: 0, label: '线上签约-标准合同'},
{value: 1, label: '线下签约'},
{value: 2, label: '线上签约-双方协商合同'},
]
},
// {
// key: "remark",
// title: "备注",
// type: "text",
// width: 160,
// mode: "%%"
// },
// {
// key: "_add_time",
// title: "添加时间",
// type: "datetimerange",
// width: 400,
// mode: "[]"
// },
]
},
form1: {
// 表单请求数据,此处可以设置默认值
data: {
sort: 0
},
// 表单属性
props: {
// 表单请求地址
action: "",
// 表单字段显示规则
columns: [{
key: "name",
title: "名称",
type: "text",
placeholder: "请输入分类名称"
},
{
key: "icon",
title: "图标",
type: "icon",
placeholder: "请选择图标"
},
{
key: "parent_id",
title: "上级分类",
type: "tree-select",
placeholder: "请选择上级分类",
action: "admin/spot/category/sys/getTree",
props: {
list: "rows",
value: "_id",
label: "name",
children: "children"
},
},
{
key: "remark",
title: "备注",
type: "textarea",
maxlength: "99",
showWordLimit: true,
autosize: {
minRows: 2,
maxRows: 10
},
},
{
key: "sort",
title: "排序",
type: "number",
precision: 0,
placeholder: "请输入排序值",
},
],
// 表单验证规则
rules: {
sort: [{
type: 'number',
message: '排序值必须为数字'
}],
name: [
{required: true, message: '分类名称不能为空', trigger: 'blur'},
],
},
// add 代表添加 update 代表修改
formType: "",
// 是否显示表单的弹窗
show: false
}
},
// 其他弹窗表单
formDatas: {},
// 表单相关结束 -----------------------------------------------------------
};
},
// 监听 - 页面每次【加载时】执行(如:前进)
onLoad(options = {}) {
that = this;
vk = that.vk;
that.options = options;
that.registerFilePreviewHandler();
that.init(options);
},
onUnload() {
this.unregisterFilePreviewHandler();
},
beforeDestroy() {
this.unregisterFilePreviewHandler();
this.revokePdfPreviewUrl();
},
// 监听 - 页面【首次渲染完成时】执行。注意如果渲染速度快,会在页面进入动画完成前触发
onReady() {
},
// 监听 - 页面每次【显示时】执行(如:前进和返回) (页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面)
onShow() {
},
// 监听 - 页面每次【隐藏时】执行(如:返回)
onHide() {
},
// 函数
methods: {
// 页面数据初始化函数
init(options) {
originalForms["form1"] = vk.pubfn.copyObject(that.form1);
},
registerFilePreviewHandler() {
if (typeof window === "undefined") return
window.__previewEnquiryFile = encodedUrl => {
this.previewFile(decodeURIComponent(encodedUrl))
}
},
unregisterFilePreviewHandler() {
if (typeof window === "undefined") return
if (window.__previewEnquiryFile) delete window.__previewEnquiryFile
},
// 页面跳转
pageTo(path) {
vk.navigateTo(path);
},
// 表单重置
resetForm() {
vk.pubfn.resetForm(originalForms, that);
},
// 搜索
search() {
that.$refs.table1.search();
},
// 刷新
refresh() {
that.$refs.table1.refresh();
},
// 获取当前选中的行的数据
getCurrentRow() {
return that.$refs.table1.getCurrentRow();
},
// 监听 - 行的选中高亮事件
currentChange(val) {
that.table1.selectItem = val;
},
// 当选择项发生变化时会触发该事件
selectionChange(list) {
that.table1.multipleSelection = list;
},
// 显示添加页面
addBtn() {
that.resetForm();
that.form1.props.action = 'admin/contract/template/sys/add';
that.form1.props.formType = 'add';
that.form1.props.title = '添加';
that.form1.props.show = true;
},
// 显示修改页面
updateBtn({
item
}) {
that.form1.props.action = 'admin/contract/template/sys/update';
that.form1.props.formType = 'update';
that.form1.props.title = '编辑';
that.form1.props.show = true;
that.form1.data = item;
},
// 删除按钮
deleteBtn({
item,
deleteFn
}) {
deleteFn({
action: "admin/contract/template/sys/delete",
data: {
_id: item._id
},
});
},
// 监听 - 批量操作的按钮点击事件
batchBtn(index) {
switch (index) {
case 1:
vk.toast("批量操作按钮1");
break;
case 2:
vk.toast("批量操作按钮2");
break;
default:
break;
}
},
changeField(id, field, value) {
vk.callFunction({
url: 'admin/enquiry/sys/changeField',
data: {
id, field, value
}
}).then(() => {
this.$refs.table1.refresh()
})
},
doShowInfo(info) {
this.info = info
this.title = '详情'
this.showInfo = true
},
showQuoteList({_id}) {
this.$refs.EnquiryQuoteList.open(_id)
},
showPayList(row) {
this.$refs.PayList.open(row.payList)
},
changeQuoteAmount(value, id) {
this.changeField(id, 'quoteAmount', value)
},
changeNotaryServiceRate(value, row) {
const nextValue = value === undefined || value === null || value === '' ? DEFAULT_NOTARY_SERVICE_RATE : value
row.notaryServiceRate = nextValue
this.changeField(row._id, 'notaryServiceRate', nextValue)
},
getFileExt(url = "") {
const cleanUrl = String(url).split("?")[0].split("#")[0]
const match = cleanUrl.match(/\.([a-z0-9]+)$/i)
return match ? match[1].toLowerCase() : ""
},
isImageFile(url) {
return ["png", "jpg", "jpeg", "gif", "webp", "bmp", "svg"].includes(this.getFileExt(url))
},
isPdfFile(url) {
return this.getFileExt(url) === "pdf"
},
isOfficeFile(url) {
return ["doc", "docx", "xls", "xlsx", "ppt", "pptx"].includes(this.getFileExt(url))
},
getOfficePreviewUrl(url) {
return `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(url)}`
},
revokePdfPreviewUrl() {
if (this.pdfObjectUrl) {
URL.revokeObjectURL(this.pdfObjectUrl)
this.pdfObjectUrl = ''
}
this.pdfPreviewUrl = ''
},
async previewPdfFile(url) {
this.revokePdfPreviewUrl()
try {
const response = await fetch(url)
if (!response.ok) throw new Error('PDF加载失败')
const blob = await response.blob()
this.pdfObjectUrl = URL.createObjectURL(new Blob([blob], {type: 'application/pdf'}))
this.pdfPreviewUrl = this.pdfObjectUrl
} catch (e) {
this.pdfPreviewUrl = `https://mozilla.github.io/pdf.js/web/viewer.html?file=${encodeURIComponent(url)}`
}
this.showPdfPreview = true
},
previewFile(url) {
if (!url) return
if (this.isImageFile(url)) {
this.previewImageUrl = url
this.showImagePreview = true
return
}
if (this.isPdfFile(url)) {
this.previewPdfFile(url)
return
}
if (this.isOfficeFile(url)) {
window.open(this.getOfficePreviewUrl(url), "_blank")
return
}
window.open(url, "_blank")
},
},
// 监听属性
watch: {},
// 过滤器
filters: {},
// 计算属性
computed: {}
};
</script>
<style lang="scss" scoped>
.page-body {
}
.preview-image {
display: block;
max-width: 100%;
max-height: 75vh;
margin: 0 auto;
}
.pdf-preview-frame {
display: block;
width: 100%;
height: 75vh;
border: 0;
}
</style>
+546
View File
@@ -0,0 +1,546 @@
<template>
<view class="page-body">
<!-- 页面内容开始 -->
<!-- 表格搜索组件开始 -->
<vk-data-table-query v-model="queryForm1.formData" :columns="queryForm1.columns"
@search="search"></vk-data-table-query>
<!-- 表格搜索组件结束 -->
<!-- 自定义按钮区域开始 -->
<view>
<el-row>
</el-row>
</view>
<!-- 自定义按钮区域结束 -->
<!-- 表格组件开始 -->
<vk-data-table ref="table1" :action="table1.action" :columns="table1.columns" :query-form-param="queryForm1"
:pagination="true" @current-change="currentChange"
>
<template v-slot:action="{ row, column, index }">
<el-button type="primary" @click.native="showInvoice(row)">上传/查看发票</el-button>
</template>
<template v-slot:isInvoice="{ row, column, index }">
<el-switch v-model="row.isInvoice" :inactive-value="1" :active-value="2" active-text="已开" inactive-text="未开"
@change="changeField(row._id, 'isInvoice', $event)"></el-switch>
</template>
<template v-slot:invoice="{ row, column, index }">
<p>名称: {{ row.name }}</p>
<p>税号: {{ row.code }}</p>
<p>手机号: {{ row.phone }}</p>
<!-- <p>电子邮箱: {{ row.email }}</p>-->
<p>开户行: {{ row.bankName }}</p>
<p>银行账号: {{ row.bankAccount }}</p>
<!-- <p>单位地址: {{ row.address }}</p>-->
</template>
</vk-data-table>
<!-- 表格组件结束 -->
<!-- 添加或编辑的弹窗开始 -->
<vk-data-dialog v-model="form1.props.show" :title="form1.props.title" width="60%" mode="form"
:close-on-click-modal="false">
<vk-data-form v-model="form1.data" :rules="form1.props.rules" :action="form1.props.action"
:form-type="form1.props.formType" :columns='form1.props.columns' label-width="120px"
@success="form1.props.show = false;refresh();"></vk-data-form>
</vk-data-dialog>
<!-- 添加或编辑的弹窗结束 -->
<!-- 页面内容结束 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="60%">
<set-express :info="clickInfo" @close="refresh" v-if="dialogVisible && dialogType === 'express'"/>
<order-info :info="clickInfo" @close="refresh" v-if="dialogVisible && dialogType === 'info'"/>
<self-product-info :order-info="clickInfo" :order-id="clickInfo._id" :goods="clickInfo.goods"
v-if="dialogVisible && dialogType === 'self-product'"/>
<template v-if="dialogVisible && dialogType === 'invoice'">
<vk-data-upload v-model="invoice" upload-type="file" list-type="text" :show-file-list="false"
:on-success="beforeUpload" accept=".pdf"></vk-data-upload>
<a href="javascript:;" v-if="clickInfo.invoiceUrl" style="margin-top: 10px" @click="previewFile(clickInfo.invoiceUrl)">预览</a>
</template>
</el-dialog>
<el-dialog title="图片预览" :visible.sync="showImagePreview" width="80%" append-to-body>
<img v-if="previewImageUrl" class="preview-image" :src="previewImageUrl" alt="发票预览"/>
</el-dialog>
</view>
</template>
<script>
import SetExpress from "./components/setExpress.vue";
import SelfProductInfo from "./components/selfProductInfo.vue";
import OrderInfo from "./components/OrderInfo.vue";
import dayjs from 'dayjs'
var that; // 当前页面对象
var vk = uni.vk; // vk实例
var originalForms = {}; // 表单初始化数据
export default {
components: {SelfProductInfo, SetExpress, OrderInfo},
data() {
// 页面数据变量
return {
showInfo: false,
dialogTitle: null,
dialogType: null,
dialogVisible: false,
showImagePreview: false,
previewImageUrl: '',
info: null,
clickInfo: null,
title: '',
infoColumns: [],
// 页面是否请求中或加载中
loading: false,
// init请求返回的数据
data: {},
invoice: [],
// 表格相关开始 -----------------------------------------------------------
table1: {
// 表格数据请求地址
action: "admin/order/sys/getList",
// 表格字段显示规则
columns: [
{
key: "orderNo",
title: "订单号",
type: "text",
},
{
key: "type",
title: "订单类型",
type: "select",
align: "center",
data: [
{value: 0, label: '商城订单'},
{value: 1, label: '金久信自营订单'},
{value: 2, label: '保证金'},
{value: 3, label: '会员升级'},
{value: 4, label: '询价订单'},
{value: 5, label: '加工订单'},
{value: 6, label: '旧货订单'},
{value: 7, label: '报价次数'},
{value: 8, label: '现货广告'},
{value: 9, label: '旧货加急'},
{value: 10, label: '旧货次数'},
{value: 11, label: '金久信学堂下载次数'},
{value: 12, label: '司法调证'},
{value: 13, label: '金久信签约宝次数'},
{value: 14, label: '金久信签约宝'},
{value: 15, label: '金久信自营询价'},
]
},
{
key: "amount",
title: "订单金额",
type: "html",
formatter: (val = [], row, column, index) => {
let content
if (row.type !== 14) {
content = `<div>订单金额:¥` + row.amount + `</div>`
content += `<div>应付金额:¥${row.offAmount}</div>`
if (row.type < 4 && row.payAmount) {
content += `<div>实付金额:¥${row.payAmount ? row.payAmount : ''}</div>`
}
} else {
content = `<div>订单累计金额:¥` + row.amount + `</div>`
}
return content
}
},
{
key: "orderStatus",
title: "订单状态",
type: "text",
align: "center",
formatter: (val = [], row, column, index) => {
const orderStatusList = [
'待支付',
'待发货',
'待收货',
'待完成',
'已完成',
'退款审核中',
'退款成功',
'退款拒绝',
'',
'',
'待报价',
'已派单待完成',
]
let str = orderStatusList[val]
if (val === 7) str += `: ${row.refundRefuseReason}`
return str
}
},
{
key: "isInvoice",
title: "开票状态",
type: "select",
data: [
{value: 1, label: '待开票'},
{value: 2, label: '已开票'},
]
},
{
key: "invoice",
title: "开票信息",
type: "html",
},
{
key: "action",
title: "操作",
type: "html",
}
],
// 多选框选中的值
multipleSelection: [],
// 当前高亮的记录
selectItem: ""
},
// 表格相关结束 -----------------------------------------------------------
// 表单相关开始 -----------------------------------------------------------
// 查询表单请求数据
queryForm1: {
// 查询表单数据源,可在此设置默认值
formData: {
isInvoice: 1
},
// 查询表单的字段规则 fieldName:指定数据库字段名,不填默认等于key
columns: [
{
key: "orderNo",
title: "订单号",
type: "text",
width: 160,
mode: "%%"
},
{
key: "type",
title: "订单类型",
type: "select",
data: [
{value: 0, label: '商城订单'},
{value: 1, label: '金久信自营订单'},
{value: 2, label: '保证金'},
{value: 3, label: '会员升级'},
{value: 4, label: '询价订单'},
{value: 5, label: '加工订单'},
{value: 6, label: '旧货订单'},
{value: 7, label: '报价次数'},
{value: 8, label: '现货广告'},
{value: 9, label: '旧货加急'},
{value: 10, label: '旧货次数'},
{value: 11, label: '金久信学堂下载次数'},
{value: 12, label: '司法调证'},
{value: 13, label: '金久信签约宝次数'},
{value: 14, label: '金久信签约宝'},
{value: 15, label: '金久信自营询价'},
]
},
{
key: "isInvoice",
title: "开票状态",
type: "select",
data: [
{value: 1, label: '待开票'},
{value: 2, label: '已开票'},
]
},
]
},
form1: {
// 表单请求数据,此处可以设置默认值
data: {
invoiceUrl: ''
},
// 表单属性
props: {
// 表单请求地址
action: "",
// 表单字段显示规则
columns: [
{
key: "orderNo",
title: "订单号",
type: "text",
placeholder: "请输入分类名称"
},
{
key: "icon",
title: "图标",
type: "icon",
placeholder: "请选择图标"
},
{
key: "parent_id",
title: "上级分类",
type: "tree-select",
placeholder: "请选择上级分类",
action: "admin/spot/category/sys/getTree",
props: {
list: "rows",
value: "_id",
label: "name",
children: "children"
},
},
{
key: "remark",
title: "备注",
type: "textarea",
maxlength: "99",
showWordLimit: true,
autosize: {
minRows: 2,
maxRows: 10
},
},
{
key: "sort",
title: "排序",
type: "number",
precision: 0,
placeholder: "请输入排序值",
},
],
// 表单验证规则
rules: {
sort: [{
type: 'number',
message: '排序值必须为数字'
}],
name: [
{required: true, message: '分类名称不能为空', trigger: 'blur'},
],
},
// add 代表添加 update 代表修改
formType: "",
// 是否显示表单的弹窗
show: false
}
},
// 其他弹窗表单
formDatas: {},
// 表单相关结束 -----------------------------------------------------------
};
},
// 监听 - 页面每次【加载时】执行(如:前进)
onLoad(options = {}) {
that = this;
vk = that.vk;
that.options = options;
that.init(options);
},
// 监听 - 页面【首次渲染完成时】执行。注意如果渲染速度快,会在页面进入动画完成前触发
onReady() {
},
// 监听 - 页面每次【显示时】执行(如:前进和返回) (页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面)
onShow() {
},
// 监听 - 页面每次【隐藏时】执行(如:返回)
onHide() {
},
// 函数
methods: {
dayjs,
// 页面数据初始化函数
init(options) {
originalForms["form1"] = vk.pubfn.copyObject(that.form1);
},
// 页面跳转
pageTo(path) {
vk.navigateTo(path);
},
// 表单重置
resetForm() {
vk.pubfn.resetForm(originalForms, that);
},
// 搜索
search() {
that.$refs.table1.search();
},
// 刷新
refresh() {
that.$refs.table1.refresh();
this.dialogVisible = false
},
// 获取当前选中的行的数据
getCurrentRow() {
return that.$refs.table1.getCurrentRow();
},
// 监听 - 行的选中高亮事件
currentChange(val) {
that.table1.selectItem = val;
},
// 当选择项发生变化时会触发该事件
selectionChange(list) {
that.table1.multipleSelection = list;
},
// 显示添加页面
addBtn() {
that.resetForm();
that.form1.props.action = 'admin/contract/template/sys/add';
that.form1.props.formType = 'add';
that.form1.props.title = '添加';
that.form1.props.show = true;
},
// 显示修改页面
updateBtn({
item
}) {
that.form1.props.action = 'admin/contract/template/sys/update';
that.form1.props.formType = 'update';
that.form1.props.title = '编辑';
that.form1.props.show = true;
that.form1.data = item;
},
// 删除按钮
deleteBtn({
item,
deleteFn
}) {
deleteFn({
action: "admin/contract/template/sys/delete",
data: {
_id: item._id
},
});
},
// 监听 - 批量操作的按钮点击事件
batchBtn(index) {
switch (index) {
case 1:
vk.toast("批量操作按钮1");
break;
case 2:
vk.toast("批量操作按钮2");
break;
default:
break;
}
},
changeField(id, field, value) {
vk.callFunction({
url: 'admin/order/sys/changeField',
data: {
id, field, value
}
}).then(() => {
this.$refs.table1.refresh()
})
},
doShowInfo(info) {
this.info = info
this.title = '详情'
this.showInfo = true
},
setExpress(item) {
this.clickInfo = item
this.dialogType = 'express'
this.dialogTitle = '发货'
this.dialogVisible = true
},
showSelfProductInfo(item) {
this.clickInfo = item
this.dialogType = 'self-product'
this.dialogTitle = '自营订单详情'
this.dialogVisible = true
},
showOrderInfo(item) {
this.clickInfo = item
this.dialogType = 'info'
this.dialogTitle = '订单详情'
this.dialogVisible = true
},
showInvoice(item) {
this.clickInfo = item
this.invoice = (this.clickInfo.invoiceUrl) ? [this.clickInfo.invoiceUrl] : []
this.dialogType = 'invoice'
this.dialogTitle = '发票'
this.dialogVisible = true
},
changeOrderStatus(id, value) {
vk.callFunction({
url: 'admin/order/sys/changeField',
data: {
id,
field: 'orderStatus',
value
}
}).then(() => {
this.$refs.table1.refresh()
})
},
beforeUpload(file) {
vk.callFunction({
url: 'admin/order/sys/changeField',
data: {
id: this.clickInfo._id,
field: 'invoiceUrl',
value: this.invoice[this.invoice.length - 1]
}
})
this.dialogVisible = false
this.$message.success('上传成功')
this.$refs.table1.refresh()
},
uploadInvoice(row) {
console.log(row)
},
getFileExt(url = "") {
const cleanUrl = String(url).split("?")[0].split("#")[0]
const match = cleanUrl.match(/\.([a-z0-9]+)$/i)
return match ? match[1].toLowerCase() : ""
},
isImageFile(url) {
return ["png", "jpg", "jpeg", "gif", "webp", "bmp", "svg"].includes(this.getFileExt(url))
},
isPdfFile(url) {
return this.getFileExt(url) === "pdf"
},
isOfficeFile(url) {
return ["doc", "docx", "xls", "xlsx", "ppt", "pptx"].includes(this.getFileExt(url))
},
getOfficePreviewUrl(url) {
return `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(url)}`
},
previewFile(url) {
if (!url) return
if (this.isImageFile(url)) {
this.previewImageUrl = url
this.showImagePreview = true
return
}
if (this.isPdfFile(url)) {
window.open(url, "_blank")
return
}
if (this.isOfficeFile(url)) {
window.open(this.getOfficePreviewUrl(url), "_blank")
return
}
window.open(url, "_blank")
}
},
// 监听属性
watch: {},
// 过滤器
filters: {},
// 计算属性
computed: {}
};
</script>
<style lang="scss" scoped>
.page-body {
}
.preview-image {
display: block;
max-width: 100%;
max-height: 75vh;
margin: 0 auto;
}
</style>
+898
View File
@@ -0,0 +1,898 @@
<template>
<view class="page-body">
<!-- 页面内容开始 -->
<!-- 表格搜索组件开始 -->
<vk-data-table-query v-model="queryForm1.formData" :columns="queryForm1.columns"
@search="search"></vk-data-table-query>
<!-- 表格搜索组件结束 -->
<!-- 自定义按钮区域开始 -->
<view>
<el-row>
</el-row>
</view>
<!-- 自定义按钮区域结束 -->
<!-- 表格组件开始 -->
<vk-data-table ref="table1" :action="table1.action" :columns="table1.columns" :query-form-param="queryForm1"
:pagination="true" @current-change="currentChange"
>
<template v-slot:action="{ row, column, index }">
<el-button size="mini" @click.native="doShowInfo(row)">详情</el-button>
<el-button size="mini" @click.native="showQuoteList(row)" v-if="row.quoteNum > 0">报价列表</el-button>
</template>
<template v-slot:isShow="{ row, column, index }">
<el-switch v-if="row.status === 0" v-model="row.isShow" size="mini"
@change="changeField(row._id, 'isShow', $event)" :active-value="1"
:inactive-value="0"/>
<span v-else></span>
</template>
<template v-slot:isUrgent="{ row, column, index }">
<el-switch v-if="row.status === 0" v-model="row.isUrgent" size="mini"
@change="changeField(row._id, 'isUrgent', $event)" :active-value="true"
:inactive-value="false"/>
<span v-else></span>
</template>
<template v-slot:quoteAmount="{ row, column, index }">
<el-input-number v-model="row.quoteAmount" @change="changeQuoteAmount($event, row._id)"/>
</template>
</vk-data-table>
<!-- 表格组件结束 -->
<!-- 添加或编辑的弹窗开始 -->
<vk-data-dialog v-model="form1.props.show" :title="form1.props.title" width="60%" mode="form"
:close-on-click-modal="false">
<vk-data-form v-model="form1.data" :rules="form1.props.rules" :action="form1.props.action"
:form-type="form1.props.formType" :columns='form1.props.columns' label-width="120px"
@success="form1.props.show = false;refresh();"></vk-data-form>
</vk-data-dialog>
<!-- 添加或编辑的弹窗结束 -->
<!-- 页面内容结束 -->
<vk-data-dialog
v-model="showInfo"
:title="title"
width="60%"
top="14vh"
center
:close-on-click-modal="true"
>
<div style="display: flex;align-items: flex-start;flex-direction: column;justify-content: flex-start;"
v-if="showInfo && info">
<div class="row">
<span class="title">类型</span>
<span v-if="info.type === 0">拍卖</span>
<span v-if="info.type === 1">采购</span>
<span v-if="info.type === 2">租赁</span>
<span v-if="info.type === 3">物资回收</span>
</div>
<div class="row" v-if="info.type === 2">
<span class="title">租赁类型</span>
<span v-if="info.rentType === 0">承租信息</span>
<span v-if="info.rentType === 1">出租信息</span>
</div>
<div class="row">
<span class="title">分类</span>
<span>{{ info.category }}</span>
</div>
<div class="row">
<span class="title">标题</span>
<span>{{ info.title }}</span>
</div>
<div class="row">
<span class="title">详情</span>
<span>{{ info.desc }}</span>
</div>
<div class="row">
<span class="title">附件</span>
<a href="javascript:;" v-for="(item, index) in info.files" :key="index" @click="previewFile(item)">预览:文件{{ index + 1 }}</a>
</div>
<div class="row">
<span class="title">物资所在地</span>
<span>{{
(info.addressRegion && info.addressRegion.province && info.addressRegion.province.name) ? `${info.addressRegion.province.name}${info.addressRegion.city.name}${info.addressRegion.area.name}` : ''
}}</span>
</div>
<div class="row">
<span class="title">物资交货地</span>
<span>{{
(info.deliverAddressRegion && info.deliverAddressRegion.province && info.deliverAddressRegion.province.name) ? `${info.deliverAddressRegion.province.name}${info.deliverAddressRegion.city.name}${info.deliverAddressRegion.area.name}` : ''
}}</span>
</div>
<div class="row">
<span class="title">报价区域</span>
<span>{{
(info.offerAddressRegion && info.offerAddressRegion.province && info.offerAddressRegion.province.name) ? `${info.offerAddressRegion.province.name}${info.offerAddressRegion.city.name}${info.offerAddressRegion.area.name}` : ''
}}</span>
</div>
<div class="row">
<span class="title">起拍计价单位</span>
<span>{{ info.unit }}</span>
</div>
<div class="row">
<span class="title">起拍人民币单价</span>
<span>{{ info.startAmount }}</span>
</div>
<div class="row">
<span class="title">拍卖信息失效时间</span>
<span>{{ dayjs(info.expiredTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
</div>
<div class="row">
<span class="title">付款方式</span>
<span>{{ info.payMethod }}</span>
</div>
<div class="row">
<span class="title">预付比例</span>
<span>{{ info.prePayRate }}%</span>
</div>
<div class="row">
<span class="title">是否含税</span>
<span v-if="info.invoice">含税</span>
<span v-else>不含税</span>
</div>
<div class="row">
<span class="title">开票时间</span>
<span v-if="info.writeInvoiceTime === 0">付款当月(限20号之前付款,20号之后付款次月开票)</span>
<span v-if="info.writeInvoiceTime === 1">付款后次月</span>
<span v-if="info.writeInvoiceTime === 2">付款前</span>
</div>
<template v-if="!info.invoiceOther">
<div class="row">
<span class="title">纳税人身份</span>
<span>{{ info.taxType }}</span>
</div>
<div class="row">
<span class="title">发票种类</span>
<span>{{ info.invoiceType }}</span>
</div>
<div class="row">
<span class="title">税率</span>
<span>{{ info.taxRate }}</span>
</div>
</template>
<div class="row">
<span class="title">手动填写税票要求</span>
<span>{{ info.invoiceOther }}</span>
</div>
<div class="row">
<span class="title">报价详情</span>
<span>{{ info.invoiceDetail }}</span>
</div>
<div class="row">
<span class="title">报价失效时间</span>
<span>{{ info.offerExpiredTime }}</span>
</div>
<div class="row">
<span class="title">报价形式</span>
<span v-if="info.offerType === 0">整单报价</span>
<span v-if="info.offerType === 1">可分项报价</span>
</div>
<div class="row">
<span class="title">签约模式</span>
<span v-if="info.signMethod === 0">线上签约-标准合同</span>
<span v-if="info.signMethod === 1">线下签约</span>
<span v-if="info.signMethod === 2">线上签约-双方协商合同</span>
</div>
<div class="row" v-if="info.signMethod === 2">
<span class="title">合同文件</span>
<template v-if="info.contract && info.contract.contractBase">
<a href="javascript:;" v-for="(item, index) in getFileList(info.contract.contractBase)" :key="index" @click="previewFile(item)">预览文件{{ getFileList(info.contract.contractBase).length > 1 ? index + 1 : '' }}</a>
</template>
</div>
<template v-if="info.type !== 2">
<div class="row">
<span class="title">供应商信息</span>
<span>{{ info.supplier ? info.supplier.companyName : '' }}</span>
</div>
<div class="row">
<span class="title">供应商联系方式</span>
<span>{{ info.supplier ? info.supplier.contract : '' }}</span>
</div>
<div class="row">
<span class="title">供应商授权人姓名</span>
<span>{{ info.supplier ? info.supplier.managerName : '' }}</span>
</div>
<div class="row">
<span class="title">供应商授权联系方式</span>
<span>{{ info.supplier ? info.supplier.managerContract : ''}}</span>
</div>
<div class="row">
<span class="title">采购商信息</span>
<span>{{ info.buyer? info.buyer.companyName : '' }}</span>
</div>
<div class="row">
<span class="title">采购商联系方式</span>
<span>{{ info.buyer ? info.buyer.contract : '' }}</span>
</div>
<div class="row">
<span class="title">采购授权人姓名</span>
<span>{{ info.buyer ? info.buyer.managerName : '' }}</span>
</div>
<div class="row">
<span class="title">采购商授权联系方式</span>
<span>{{ info.buyer ? info.buyer.managerContract : ''}}</span>
</div>
</template>
<template v-else>
<div class="row">
<span class="title">{{ info.rentType === 0 ? '承租方' : '出租方' }}信息</span>
<span>{{ info.supplier? info.supplier.companyName : '' }}</span>
</div>
<div class="row">
<span class="title">{{ info.rentType === 0 ? '承租方' : '出租方' }}联系方式</span>
<span>{{ info.supplier ? info.supplier.contract : '' }}</span>
</div>
<div class="row">
<span class="title">{{ info.rentType === 0 ? '承租方' : '出租方' }}授权人姓名</span>
<span>{{ info.supplier ? info.supplier.managerName : '' }}</span>
</div>
<div class="row">
<span class="title">{{ info.rentType === 0 ? '承租方' : '出租方' }}授权联系方式</span>
<span>{{ info.supplier ? info.supplier.managerContract : '' }}</span>
</div>
</template>
</div>
<!-- <vk-data-detail-table-->
<!-- :data="info"-->
<!-- size="medium"-->
<!-- label-width="150px"-->
<!-- >-->
<!-- <template v-slot:columns="{ column, index }"> -->
<!-- </template>-->
<!-- </vk-data-detail-table>-->
</vk-data-dialog>
<el-dialog title="图片预览" :visible.sync="showImagePreview" width="80%" append-to-body>
<img v-if="previewImageUrl" class="preview-image" :src="previewImageUrl" alt="附件预览"/>
</el-dialog>
<el-dialog title="PDF预览" :visible.sync="showPdfPreview" width="80%" append-to-body @closed="revokePdfPreviewUrl">
<iframe v-if="pdfPreviewUrl" class="pdf-preview-frame" :src="pdfPreviewUrl"></iframe>
</el-dialog>
<OldQuoteList ref="OldQuoteList"/>
</view>
</template>
<script>
import OldQuoteList from "./components/OldQuoteList.vue";
import dayjs from "dayjs";
var that; // 当前页面对象
var vk = uni.vk; // vk实例
var originalForms = {}; // 表单初始化数据
function escapeHtml(value = "") {
return String(value)
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#39;");
}
function formatPreviewLinks(files = []) {
const list = Array.isArray(files) ? files : (files ? [files] : []);
return list
.filter(Boolean)
.map((item, itemIndex) => {
const url = encodeURIComponent(item);
const label = escapeHtml(`预览:文件${itemIndex + 1}`);
return `<a href="javascript:;" onclick="window.__previewOldFile && window.__previewOldFile('${url}')">${label}</a> `;
})
.join("");
}
export default {
components: {OldQuoteList},
data() {
// 页面数据变量
return {
showInfo: false,
info: null,
title: '',
showImagePreview: false,
previewImageUrl: '',
showPdfPreview: false,
pdfPreviewUrl: '',
pdfObjectUrl: '',
infoColumns: [
{
key: "type", title: "类型", type: "select",
data: [
{value: 0, label: '拍卖'},
{value: 1, label: '采购'},
{value: 2, label: '租赁'},
{value: 3, label: '物资回收'},
]
},
{
key: "rentType", title: "租赁类型", type: "select",
data: [
{value: 0, label: '拍卖'},
{value: 1, label: '采购'},
{value: 2, label: '租赁'},
{value: 3, label: '物资回收'},
],
show: formData => {
return formData.type === 2
}
},
{
key: "category", title: "分类", type: "array",
},
{key: "title", title: "标题", type: "text"},
{key: "desc", title: "详情", type: "text"},
{
key: "files", title: "附件", type: "html",
formatter: (val = [], row, column, index) => {
return formatPreviewLinks(val)
}
},
{
key: "addressRegion",
title: "物资所在地",
type: "address",
formatter: (val, row, column, index) => {
return `${val.province.name}`
}
},
{
key: "deliverAddressRegion",
title: "物资交货地",
type: "text",
formatter: (val, row, column, index) => {
return `${val.province.name} ${val.city.name} ${val.area.name} ${row.deliverAddressDetail}`
},
showRule: formData => {
return [1, 2].includes(formData.type)
}
},
{
key: "offerAddressRegion",
title: "报价区域",
type: "address"
},
{
key: "unit", title: "起拍计价单位", type: "text",
// formatter: (val, row, column, index) => {
// return `${row.startNum ? row.startNum : ''} ${row.unit ? row.unit : ''}`
// },
},
{
key: "startAmount", title: "起拍人民币单价", type: "text",
formatter: (val, row, column, index) => {
return val ? `${val}元` : ''
},
},
{key: "expiredTime", title: "拍卖信息失效时间", type: "text"},
{
key: "payMethod", title: "付款方式", type: "text",
},
{
key: "prePayRate", title: "预付比例", type: "text",
},
{
key: "invoice", title: "是否含税", type: "radio", data: [
{label: "含税", value: true},
{label: "不含税", value: false}
]
},
{
key: "writeInvoiceTime", title: "开票时间", type: "radio", data: [
{label: "付款当月(限20号之前付款,20号之后付款次月开票)", value: 0},
{label: "付款后次月", value: 1},
{label: "付款前", value: 2}
]
},
// {
// key: "invoiceType", title: "发票种类", type: "radio", data: [
// {label: "增值税专用发票13%", value: 0},
// {label: "增值税普通发票", value: 1},
// {label: "普通发票", value: 2}
// ]
// },
// {key: "invoiceOther", title: "发票其他要求", type: "text"},
{
key: "taxType", title: "纳税人身份", type: "text", showRule: formData => {
return !!formData.invoiceOther
}
},
{
key: "invoiceType", title: "发票种类", type: "text", showRule: formData => {
return !!formData.invoiceOther
}
},
{
key: "taxRate", title: "税率", type: "text", showRule: formData => {
return !!formData.invoiceOther
}
},
{
key: "invoiceOther", title: "手动填写税票要求", type: "text", showRule: formData => {
console.log(formData)
return !!formData.taxType
}
},
{key: "invoiceDetail", title: "报价详情", type: "text"},
{key: "offerExpiredTime", title: "报价失效时间", type: "time"},
{
key: "offerType", title: "报价形式", type: "radio", data: [
{label: "整单报价", value: 0},
{label: "可分项报价", value: 1}
]
},
{
key: "signMethod", title: "签约模式", type: "radio", data: [
{label: "线上签约-标准合同", value: 0},
{label: "线下签约", value: 1},
{label: "线上签约-双方协商合同", value: 2},
]
},
{key: "supplier.companyName", title: "供应商信息", type: "text"},
{key: "supplier.contract", title: "供应商联系方式", type: "text"},
{key: "supplier.managerName", title: "供应商授权人姓名", type: "text"},
{key: "supplier.managerContract", title: "供应商授权联系方式", type: "text"},
{key: "buyer.companyName", title: "采购商信息", type: "text"},
{key: "buyer.contract", title: "采购商联系方式", type: "text"},
{key: "buyer.managerName", title: "采购授权人姓名", type: "text"},
{key: "buyer.managerContract", title: "采购商授权联系方式", type: "text"},
],
// 页面是否请求中或加载中
loading: false,
// init请求返回的数据
data: {},
// 表格相关开始 -----------------------------------------------------------
table1: {
// 表格数据请求地址
action: "admin/old/sys/getList",
// 表格字段显示规则
columns: [
{
key: "title",
title: "标题",
type: "text",
align: "left",
width: 200
},
{
key: "type",
title: "类型",
type: "select",
data: [
{value: 0, label: '拍卖'},
{value: 1, label: '采购'},
{value: 2, label: '租赁'},
{value: 3, label: '物资回收'},
]
},
{
key: "rentType", title: "租赁类型", type: "select",
data: [
{value: 0, label: '承租信息'},
{value: 1, label: '出租信息'},
],
showRow: (row) => {
return row.type === 2
}
},
{
key: "category",
title: "分类",
type: "text",
align: "left",
width: 180,
formatter: (val, row, column, index) => {
return val[1]
}
},
{
key: "",
title: "报价情况",
type: "text",
align: "left",
formatter: (val = [], row, column, index) => {
return `${row.quoteNum}家`
}
},
{
key: "status",
title: "状态",
type: "tag",
data: [
{value: 0, label: '未选商'},
{value: 1, label: '已选商', tagType: 'danger'},
{value: 2, label: '已完成', tagType: 'success'},
]
},
{key: "isUrgent", title: "是否加急", type: "html"},
{key: "isShow", title: "是否显示", type: "html"},
{key: "quoteAmount", title: "单次报价金额", type: "html", width: 210,},
{
key: "_add_time",
title: "添加时间",
type: "time",
align: "left",
width: 160,
sortable: "custom"
},
{
key: "_add_time_diff",
title: "距离现在",
type: "html",
align: "left",
width: 120,
formatter: (val, row) => vk.pubfn.dateDiff(row._add_time)
},
{key: "action", title: "操作", type: "html", width: 220,},
],
// 多选框选中的值
multipleSelection: [],
// 当前高亮的记录
selectItem: ""
},
// 表格相关结束 -----------------------------------------------------------
// 表单相关开始 -----------------------------------------------------------
// 查询表单请求数据
queryForm1: {
// 查询表单数据源,可在此设置默认值
formData: {},
// 查询表单的字段规则 fieldName:指定数据库字段名,不填默认等于key
columns: [
{
key: "title",
title: "标题",
type: "text",
width: 160,
mode: "%%"
},
{
key: "type",
title: "类型",
type: "select",
data: [
{value: 0, label: '拍卖'},
{value: 1, label: '采购'},
{value: 2, label: '租赁'},
{value: 3, label: '物资回收'},
]
},
{
key: "rentType", title: "租赁类型", type: "select",
data: [
{value: 0, label: '承租信息'},
{value: 1, label: '出租信息'},
],
showRow: (row) => {
return row.type === 2
}
},
{
key: "status",
title: "状态",
type: "select",
data: [
{value: 0, label: '未选商'},
{value: 1, label: '已选商'},
{value: 2, label: '已完成'},
]
},
{
key: "signMethod",
title: "签约方式",
type: "select",
data: [
{value: 0, label: '线上签约-标准合同'},
{value: 1, label: '线下签约'},
{value: 2, label: '线上签约-双方协商合同'},
]
},
]
},
form1: {
// 表单请求数据,此处可以设置默认值
data: {
sort: 0
},
// 表单属性
props: {
// 表单请求地址
action: "",
// 表单字段显示规则
columns: [{
key: "name",
title: "名称",
type: "text",
placeholder: "请输入分类名称"
},
{
key: "icon",
title: "图标",
type: "icon",
placeholder: "请选择图标"
},
{
key: "parent_id",
title: "上级分类",
type: "tree-select",
placeholder: "请选择上级分类",
action: "admin/spot/category/sys/getTree",
props: {
list: "rows",
value: "_id",
label: "name",
children: "children"
},
},
{
key: "remark",
title: "备注",
type: "textarea",
maxlength: "99",
showWordLimit: true,
autosize: {
minRows: 2,
maxRows: 10
},
},
{
key: "sort",
title: "排序",
type: "number",
precision: 0,
placeholder: "请输入排序值",
},
],
// 表单验证规则
rules: {
sort: [{
type: 'number',
message: '排序值必须为数字'
}],
name: [
{required: true, message: '分类名称不能为空', trigger: 'blur'},
],
},
// add 代表添加 update 代表修改
formType: "",
// 是否显示表单的弹窗
show: false
}
},
// 其他弹窗表单
formDatas: {},
// 表单相关结束 -----------------------------------------------------------
};
},
// 监听 - 页面每次【加载时】执行(如:前进)
onLoad(options = {}) {
that = this;
vk = that.vk;
that.options = options;
that.registerFilePreviewHandler();
that.init(options);
},
onUnload() {
this.unregisterFilePreviewHandler();
},
beforeDestroy() {
this.unregisterFilePreviewHandler();
this.revokePdfPreviewUrl();
},
// 监听 - 页面【首次渲染完成时】执行。注意如果渲染速度快,会在页面进入动画完成前触发
onReady() {
},
// 监听 - 页面每次【显示时】执行(如:前进和返回) (页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面)
onShow() {
},
// 监听 - 页面每次【隐藏时】执行(如:返回)
onHide() {
},
// 函数
methods: {
dayjs,
// 页面数据初始化函数
init(options) {
originalForms["form1"] = vk.pubfn.copyObject(that.form1);
},
registerFilePreviewHandler() {
if (typeof window === "undefined") return
window.__previewOldFile = encodedUrl => {
this.previewFile(decodeURIComponent(encodedUrl))
}
},
unregisterFilePreviewHandler() {
if (typeof window === "undefined") return
if (window.__previewOldFile) delete window.__previewOldFile
},
getFileList(files) {
return Array.isArray(files) ? files : (files ? [files] : [])
},
// 页面跳转
pageTo(path) {
vk.navigateTo(path);
},
// 表单重置
resetForm() {
vk.pubfn.resetForm(originalForms, that);
},
// 搜索
search() {
that.$refs.table1.search();
},
// 刷新
refresh() {
that.$refs.table1.refresh();
},
// 获取当前选中的行的数据
getCurrentRow() {
return that.$refs.table1.getCurrentRow();
},
// 监听 - 行的选中高亮事件
currentChange(val) {
that.table1.selectItem = val;
},
// 当选择项发生变化时会触发该事件
selectionChange(list) {
that.table1.multipleSelection = list;
},
// 显示添加页面
addBtn() {
that.resetForm();
that.form1.props.action = 'admin/contract/template/sys/add';
that.form1.props.formType = 'add';
that.form1.props.title = '添加';
that.form1.props.show = true;
},
// 显示修改页面
updateBtn({
item
}) {
that.form1.props.action = 'admin/contract/template/sys/update';
that.form1.props.formType = 'update';
that.form1.props.title = '编辑';
that.form1.props.show = true;
that.form1.data = item;
},
// 删除按钮
deleteBtn({
item,
deleteFn
}) {
deleteFn({
action: "admin/contract/template/sys/delete",
data: {
_id: item._id
},
});
},
// 监听 - 批量操作的按钮点击事件
batchBtn(index) {
switch (index) {
case 1:
vk.toast("批量操作按钮1");
break;
case 2:
vk.toast("批量操作按钮2");
break;
default:
break;
}
},
changeField(id, field, value) {
vk.callFunction({
url: 'admin/old/sys/changeField',
data: {
id, field, value
}
}).then(() => {
this.$refs.table1.refresh()
})
},
doShowInfo(info) {
this.info = info
this.title = '详情'
this.showInfo = true
},
showQuoteList({_id}) {
this.$refs.OldQuoteList.open(_id)
},
changeQuoteAmount(value, id) {
this.changeField(id, 'quoteAmount', value)
},
getFileExt(url = "") {
const cleanUrl = String(url).split("?")[0].split("#")[0]
const match = cleanUrl.match(/\.([a-z0-9]+)$/i)
return match ? match[1].toLowerCase() : ""
},
isImageFile(url) {
return ["png", "jpg", "jpeg", "gif", "webp", "bmp", "svg"].includes(this.getFileExt(url))
},
isPdfFile(url) {
return this.getFileExt(url) === "pdf"
},
isOfficeFile(url) {
return ["doc", "docx", "xls", "xlsx", "ppt", "pptx"].includes(this.getFileExt(url))
},
getOfficePreviewUrl(url) {
return `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(url)}`
},
revokePdfPreviewUrl() {
if (this.pdfObjectUrl) {
URL.revokeObjectURL(this.pdfObjectUrl)
this.pdfObjectUrl = ''
}
this.pdfPreviewUrl = ''
},
async previewPdfFile(url) {
this.revokePdfPreviewUrl()
try {
const response = await fetch(url)
if (!response.ok) throw new Error('PDF加载失败')
const blob = await response.blob()
this.pdfObjectUrl = URL.createObjectURL(new Blob([blob], {type: 'application/pdf'}))
this.pdfPreviewUrl = this.pdfObjectUrl
} catch (e) {
this.pdfPreviewUrl = `https://mozilla.github.io/pdf.js/web/viewer.html?file=${encodeURIComponent(url)}`
}
this.showPdfPreview = true
},
previewFile(url) {
if (!url) return
if (this.isImageFile(url)) {
this.previewImageUrl = url
this.showImagePreview = true
return
}
if (this.isPdfFile(url)) {
this.previewPdfFile(url)
return
}
if (this.isOfficeFile(url)) {
window.open(this.getOfficePreviewUrl(url), "_blank")
return
}
window.open(url, "_blank")
},
},
// 监听属性
watch: {},
// 过滤器
filters: {},
// 计算属性
computed: {}
};
</script>
<style lang="scss" scoped>
.row {
display: flex;
align-items: center;
justify-content: flex-start;
border: 1px solid #F5F7F9;
width: 100%;
* {
padding: 20px;
}
.title {
font-weight: bold;
background-color: #F5F7F9;
width: 300px;
}
}
.preview-image {
display: block;
max-width: 100%;
max-height: 75vh;
margin: 0 auto;
}
.pdf-preview-frame {
display: block;
width: 100%;
height: 75vh;
border: 0;
}
</style>
+539
View File
@@ -0,0 +1,539 @@
<template>
<view class="page-body">
<!-- 页面内容开始 -->
<!-- 表格搜索组件开始 -->
<vk-data-table-query v-model="queryForm1.formData" :columns="queryForm1.columns"
@search="search"></vk-data-table-query>
<!-- 表格搜索组件结束 -->
<!-- 自定义按钮区域开始 -->
<view>
<el-row>
</el-row>
</view>
<!-- 自定义按钮区域结束 -->
<!-- 表格组件开始 -->
<vk-data-table ref="table1" :action="table1.action" :columns="table1.columns" :query-form-param="queryForm1"
:pagination="true" @current-change="currentChange"
>
<template v-slot:action="{ row, column, index }">
<template v-if="row.type === 0 && row.orderStatus === 1">
<!-- <el-button type="success" size="mini" @click.native="setExpress(row)">发货</el-button>-->
</template>
<template v-if="row.type === 0">
<el-button size="mini" @click.native="showOrderInfo(row)">详情</el-button>
<!-- <template v-if="[5, 7].includes(row.orderStatus)">-->
<!-- <el-button size="mini" type="success" @click.native="changeOrderStatus(row._id, 6)">同意退款-->
<!-- </el-button>-->
<!-- <el-button size="mini" type="danger" @click.native="changeOrderStatus(row._id, 7)">拒绝退款-->
<!-- </el-button>-->
<!-- </template>-->
</template>
<template v-if="row.type === 1">
<el-button size="mini" plain @click.native="showSelfProductInfo(row)">详情</el-button>
</template>
</template>
<template v-slot:goods="{ row, column, index }">
<div v-for="(item, index) in row.goods" :key="index" style="
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;">
<p>商品名称: {{ item.goodsName }}</p>
<p v-if="row.type === 0 && formatSku(item.sku)">规格: {{ formatSku(item.sku) }}</p>
<p>数量: x{{ item.num }}</p>
<p>单价: {{ item.goodsPrice }}元</p>
<template v-if="row.type === 7 && item.isSingleQuote">
<view v-if="item.type === 'enquiry'">报价类型:找买家</view>
<view v-if="item.type === 'old'">报价类型:旧货交易</view>
<view v-if="item.type === 'process'">报价类型:找加工</view>
<view>报价内容:{{ item.sheet.title }}</view>
</template>
<template v-if="row.type === 7 && !item.isSingleQuote">
<view class="flex justify-start items-center">
<span>{{ item.goodsName }}</span>
<span class="text-main">(过期时间:{{
dayjs(row.user.quoteExpiredAt).format('YYYY-MM-DD HH:mm:ss')
}})</span>
</view>
</template>
<p v-if="row.type === 0 && item.company">所属公司: {{ item.company.company.companyName }}</p>
<el-divider v-if="index < row.goods.length - 1"/>
</div>
</template>
</vk-data-table>
<!-- 表格组件结束 -->
<!-- 添加或编辑的弹窗开始 -->
<vk-data-dialog v-model="form1.props.show" :title="form1.props.title" width="60%" mode="form"
:close-on-click-modal="false">
<vk-data-form v-model="form1.data" :rules="form1.props.rules" :action="form1.props.action"
:form-type="form1.props.formType" :columns='form1.props.columns' label-width="120px"
@success="form1.props.show = false;refresh();"></vk-data-form>
</vk-data-dialog>
<!-- 添加或编辑的弹窗结束 -->
<!-- 页面内容结束 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="60%">
<set-express :info="clickInfo" @close="refresh" v-if="dialogVisible && dialogType === 'express'"/>
<order-info :info="clickInfo" @close="refresh" v-if="dialogVisible && dialogType === 'info'"/>
<self-product-info :order-info="clickInfo" :order-id="clickInfo._id" :goods="clickInfo.goods"
v-if="dialogVisible && dialogType === 'self-product'"/>
</el-dialog>
</view>
</template>
<script>
import SetExpress from "./components/setExpress.vue";
import SelfProductInfo from "./components/selfProductInfo.vue";
import OrderInfo from "./components/OrderInfo.vue";
import dayjs from 'dayjs'
var that; // 当前页面对象
var vk = uni.vk; // vk实例
var originalForms = {}; // 表单初始化数据
export default {
components: {SelfProductInfo, SetExpress, OrderInfo},
data() {
// 页面数据变量
return {
showInfo: false,
dialogTitle: null,
dialogType: null,
dialogVisible: false,
info: null,
clickInfo: null,
title: '',
infoColumns: [],
// 页面是否请求中或加载中
loading: false,
// init请求返回的数据
data: {},
// 表格相关开始 -----------------------------------------------------------
table1: {
// 表格数据请求地址
action: "admin/order/sys/getList",
// 表格字段显示规则
columns: [
{
key: "orderNo",
title: "订单号",
type: "text",
},
{
key: "type",
title: "订单类型",
type: "select",
align: "center",
data: [
{value: 0, label: '商城订单'},
{value: 1, label: '金久信自营订单'},
{value: 2, label: '保证金'},
{value: 3, label: '会员升级'},
{value: 4, label: '询价订单'},
{value: 5, label: '加工订单'},
{value: 6, label: '旧货订单'},
{value: 7, label: '报价次数'},
{value: 8, label: '现货广告'},
{value: 9, label: '旧货加急'},
{value: 10, label: '旧货次数'},
{value: 11, label: '金久信学堂下载次数'},
{value: 12, label: '司法调证'},
{value: 13, label: '金久信签约宝次数'},
{value: 14, label: '金久信签约宝'},
{value: 15, label: '金久信自营询价'},
]
},
{
key: "amount",
title: "订单金额",
type: "html",
formatter: (val = [], row, column, index) => {
let content
if (row.type !== 14) {
content = `<div>订单金额:¥` + row.amount + `</div>`
content += `<div>应付金额:¥${row.offAmount}</div>`
if (row.type < 4 && row.payAmount) {
content += `<div>实付金额:¥${row.payAmount ? row.payAmount : ''}</div>`
}
} else {
content = `<div>订单累计金额:¥` + row.amount + `</div>`
}
return content
}
},
{
key: "orderStatus",
title: "订单状态",
type: "text",
align: "center",
formatter: (val = [], row, column, index) => {
const orderStatusList = [
'待支付',
'待发货',
'待收货',
'待完成',
'已完成',
'退款审核中',
'退款成功',
'退款拒绝',
'',
'',
'待报价',
'已派单待完成',
]
let str = orderStatusList[val]
if (val === 7) str += `: ${row.refundRefuseReason}`
return str
}
},
{
key: "user",
title: "买方",
type: "html",
formatter: (val = [], row, column, index) => {
console.log(val.accountType === 2, val.company.companyName)
let content = `<p>` + val.mobile + `</p>`
content += `<p>` + (val.accountType === 2 ? val.company.companyName : val.person.personName) + `</p>`
console.log(content)
return content
}
},
{
key: "goods",
title: "商品列表",
type: "html",
},
{
key: "remark",
title: "用户备注",
type: "text",
},
{
key: "_add_time",
title: "下单时间",
type: "time",
align: "left",
width: 160,
sortable: "custom"
},
// {
// key: "_add_time",
// title: "距离现在",
// type: "dateDiff",
// align: "left",
// width: 120
// },
{
key: "action",
title: "操作",
type: "html",
}
],
// 多选框选中的值
multipleSelection: [],
// 当前高亮的记录
selectItem: ""
},
// 表格相关结束 -----------------------------------------------------------
// 表单相关开始 -----------------------------------------------------------
// 查询表单请求数据
queryForm1: {
// 查询表单数据源,可在此设置默认值
formData: {},
// 查询表单的字段规则 fieldName:指定数据库字段名,不填默认等于key
columns: [
{
key: "orderNo",
title: "订单号",
type: "text",
width: 160,
mode: "%%"
},
{
key: "type",
title: "订单类型",
type: "select",
data: [
{value: 0, label: '商城订单'},
{value: 1, label: '金久信自营订单'},
{value: 2, label: '保证金'},
{value: 3, label: '会员升级'},
{value: 4, label: '询价订单'},
{value: 5, label: '加工订单'},
{value: 6, label: '旧货订单'},
{value: 7, label: '报价次数'},
{value: 8, label: '现货广告'},
{value: 9, label: '旧货加急'},
{value: 10, label: '旧货次数'},
{value: 11, label: '金久信学堂下载次数'},
{value: 12, label: '司法调证'},
{value: 13, label: '金久信签约宝次数'},
{value: 14, label: '金久信签约宝'},
{value: 15, label: '金久信自营询价'},
]
},
{
key: "orderStatus",
title: "订单状态",
type: "select",
data: [
{value: 0, label: '待支付'},
{value: 1, label: '待发货'},
{value: 2, label: '待收货'},
{value: 3, label: '待完成'},
{value: 4, label: '已完成'},
{value: 5, label: '退款审核中'},
{value: 6, label: '退款成功'},
{value: 7, label: '退款失败'},
{value: 10, label: '待报价'},
{value: 11, label: '已派单待完成'},
]
},
{
key: "_add_time",
title: "下单时间",
type: "datetimerange",
width: 400,
mode: "[]"
},
]
},
form1: {
// 表单请求数据,此处可以设置默认值
data: {
sort: 0
},
// 表单属性
props: {
// 表单请求地址
action: "",
// 表单字段显示规则
columns: [
{
key: "orderNo",
title: "订单号",
type: "text",
placeholder: "请输入分类名称"
},
{
key: "icon",
title: "图标",
type: "icon",
placeholder: "请选择图标"
},
{
key: "parent_id",
title: "上级分类",
type: "tree-select",
placeholder: "请选择上级分类",
action: "admin/spot/category/sys/getTree",
props: {
list: "rows",
value: "_id",
label: "name",
children: "children"
},
},
{
key: "remark",
title: "备注",
type: "textarea",
maxlength: "99",
showWordLimit: true,
autosize: {
minRows: 2,
maxRows: 10
},
},
{
key: "sort",
title: "排序",
type: "number",
precision: 0,
placeholder: "请输入排序值",
},
],
// 表单验证规则
rules: {
sort: [{
type: 'number',
message: '排序值必须为数字'
}],
name: [
{required: true, message: '分类名称不能为空', trigger: 'blur'},
],
},
// add 代表添加 update 代表修改
formType: "",
// 是否显示表单的弹窗
show: false
}
},
// 其他弹窗表单
formDatas: {},
// 表单相关结束 -----------------------------------------------------------
};
},
// 监听 - 页面每次【加载时】执行(如:前进)
onLoad(options = {}) {
that = this;
vk = that.vk;
that.options = options;
that.init(options);
},
// 监听 - 页面【首次渲染完成时】执行。注意如果渲染速度快,会在页面进入动画完成前触发
onReady() {
},
// 监听 - 页面每次【显示时】执行(如:前进和返回) (页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面)
onShow() {
},
// 监听 - 页面每次【隐藏时】执行(如:返回)
onHide() {
},
// 函数
methods: {
dayjs,
formatSku(sku) {
if (!sku) return ''
if (typeof sku === 'string') return sku
return sku.label || sku.name || sku.title || sku.specName || ''
},
// 页面数据初始化函数
init(options) {
originalForms["form1"] = vk.pubfn.copyObject(that.form1);
},
// 页面跳转
pageTo(path) {
vk.navigateTo(path);
},
// 表单重置
resetForm() {
vk.pubfn.resetForm(originalForms, that);
},
// 搜索
search() {
that.$refs.table1.search();
},
// 刷新
refresh() {
that.$refs.table1.refresh();
this.dialogVisible = false
},
// 获取当前选中的行的数据
getCurrentRow() {
return that.$refs.table1.getCurrentRow();
},
// 监听 - 行的选中高亮事件
currentChange(val) {
that.table1.selectItem = val;
},
// 当选择项发生变化时会触发该事件
selectionChange(list) {
that.table1.multipleSelection = list;
},
// 显示添加页面
addBtn() {
that.resetForm();
that.form1.props.action = 'admin/contract/template/sys/add';
that.form1.props.formType = 'add';
that.form1.props.title = '添加';
that.form1.props.show = true;
},
// 显示修改页面
updateBtn({
item
}) {
that.form1.props.action = 'admin/contract/template/sys/update';
that.form1.props.formType = 'update';
that.form1.props.title = '编辑';
that.form1.props.show = true;
that.form1.data = item;
},
// 删除按钮
deleteBtn({
item,
deleteFn
}) {
deleteFn({
action: "admin/contract/template/sys/delete",
data: {
_id: item._id
},
});
},
// 监听 - 批量操作的按钮点击事件
batchBtn(index) {
switch (index) {
case 1:
vk.toast("批量操作按钮1");
break;
case 2:
vk.toast("批量操作按钮2");
break;
default:
break;
}
},
changeField(id, field, value) {
vk.callFunction({
url: 'admin/old/sys/changeField',
data: {
id, field, value
}
}).then(() => {
this.$refs.table1.refresh()
})
},
doShowInfo(info) {
this.info = info
this.title = '详情'
this.showInfo = true
},
setExpress(item) {
this.clickInfo = item
this.dialogType = 'express'
this.dialogTitle = '发货'
this.dialogVisible = true
},
showSelfProductInfo(item) {
this.clickInfo = item
this.dialogType = 'self-product'
this.dialogTitle = '自营订单详情'
this.dialogVisible = true
},
showOrderInfo(item) {
this.clickInfo = item
this.dialogType = 'info'
this.dialogTitle = '订单详情'
this.dialogVisible = true
},
changeOrderStatus(id, value) {
vk.callFunction({
url: 'admin/order/sys/changeField',
data: {
id,
field: 'orderStatus',
value
}
}).then(() => {
this.$refs.table1.refresh()
})
},
},
// 监听属性
watch: {},
// 过滤器
filters: {},
// 计算属性
computed: {}
};
</script>
<style lang="scss" scoped>
.page-body {
}
</style>
+697
View File
@@ -0,0 +1,697 @@
<template>
<view class="page-body">
<!-- 页面内容开始 -->
<!-- 表格搜索组件开始 -->
<vk-data-table-query v-model="queryForm1.formData" :columns="queryForm1.columns"
@search="search"></vk-data-table-query>
<!-- 表格搜索组件结束 -->
<!-- 自定义按钮区域开始 -->
<view>
<el-row>
</el-row>
</view>
<!-- 自定义按钮区域结束 -->
<!-- 表格组件开始 -->
<vk-data-table ref="table1" :action="table1.action" :columns="table1.columns" :query-form-param="queryForm1"
:pagination="true" @current-change="currentChange"
>
<template v-slot:action="{ row, column, index }">
<el-button size="mini" @click.native="doShowInfo(row)">详情</el-button>
<el-button size="mini" @click.native="showQuoteList(row)" v-if="row.quoteNum > 0">报价列表</el-button>
<el-button size="mini" @click.native="showPayList(row)" v-if="row.payList">支付明细</el-button>
<el-button size="mini" @click.native="changeField(row._id, 'showInAdmin', 0)"
v-if="row.showInAdmin === 1" type="danger">删除
</el-button>
<el-button size="mini" @click.native="changeField(row._id, 'showInAdmin', 1)"
v-if="row.showInAdmin === 0" type="danger">恢复
</el-button>
</template>
<template v-slot:isShow="{ row, column, index }">
<el-switch v-if="row.status === 0" v-model="row.isShow" size="mini"
@change="changeField(row._id, 'isShow', $event)"
:active-value="1"
:inactive-value="0"/>
<span v-else></span>
</template>
<template v-slot:quoteAmount="{ row, column, index }">
<el-input-number v-model="row.quoteAmount" @change="changeQuoteAmount($event, row._id)"/>
</template>
<template v-slot:orderAmount="{ row, column, index }">
<p v-if="row.quote">报价金额: ¥{{ row.quote.totalPrice }}</p>
<p v-if="row.payList">实付金额: ¥{{
row.payList.reduce((pre, cur) => (cur.hasPaid && !cur.buyerRefuse && cur.sellerConfirm) ? parseFloat(pre) + parseFloat(cur.amount) : pre, 0)
}}</p>
</template>
</vk-data-table>
<!-- 表格组件结束 -->
<!-- 添加或编辑的弹窗开始 -->
<vk-data-dialog v-model="form1.props.show" :title="form1.props.title" width="60%" mode="form"
:close-on-click-modal="false">
<vk-data-form v-model="form1.data" :rules="form1.props.rules" :action="form1.props.action"
:form-type="form1.props.formType" :columns='form1.props.columns' label-width="120px"
@success="form1.props.show = false;refresh();"></vk-data-form>
</vk-data-dialog>
<!-- 添加或编辑的弹窗结束 -->
<!-- 页面内容结束 -->
<vk-data-dialog
v-model="showInfo"
:title="title"
width="60%"
top="14vh"
center
:close-on-click-modal="true"
>
<vk-data-detail-table
:data="info"
:columns="infoColumns"
size="medium"
label-width="150px"
>
</vk-data-detail-table>
</vk-data-dialog>
<el-dialog title="图片预览" :visible.sync="showImagePreview" width="80%" append-to-body>
<img v-if="previewImageUrl" class="preview-image" :src="previewImageUrl" alt="附件预览"/>
</el-dialog>
<el-dialog title="PDF预览" :visible.sync="showPdfPreview" width="80%" append-to-body @closed="revokePdfPreviewUrl">
<iframe v-if="pdfPreviewUrl" class="pdf-preview-frame" :src="pdfPreviewUrl"></iframe>
</el-dialog>
<ProcessQuoteList ref="ProcessQuoteList"/>
<PayList ref="PayList"/>
</view>
</template>
<script>
import ProcessQuoteList from "./components/ProcessQuoteList.vue";
var that; // 当前页面对象
var vk = uni.vk; // vk实例
var originalForms = {}; // 表单初始化数据
import provinces from "@/uni_modules/vk-uview-ui/libs/address/provinces.json";
import citys from "@/uni_modules/vk-uview-ui/libs/address/citys.json";
import areas from "@/uni_modules/vk-uview-ui/libs/address/areas.json";
import PayList from "./components/PayList.vue";
function escapeHtml(value = "") {
return String(value)
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#39;");
}
function formatPreviewLinks(files = []) {
const list = Array.isArray(files) ? files : (files ? [files] : []);
return list
.filter(Boolean)
.map((item, itemIndex) => {
const url = encodeURIComponent(item);
const label = escapeHtml(`预览:文件${itemIndex + 1}`);
return `<a href="javascript:;" onclick="window.__previewProcessFile && window.__previewProcessFile('${url}')">${label}</a> `;
})
.join("");
}
export default {
components: {PayList, ProcessQuoteList},
data() {
// 页面数据变量
return {
showInfo: false,
info: null,
title: '',
showImagePreview: false,
previewImageUrl: '',
showPdfPreview: false,
pdfPreviewUrl: '',
pdfObjectUrl: '',
provinceData: provinces,
cityData: citys,
areaData: areas,
infoColumns: [
{key: "title", title: "主要商品", type: "text"},
{key: "detail", title: "加工产品简述", type: "text"},
{key: "num", title: "加工量", type: "text"},
{
key: "files", title: "附件", type: "html",
formatter: (val = [], row, column, index) => {
return formatPreviewLinks(val)
}
},
{key: "remark", title: "采购商其他要求", type: "text"},
{
key: "multiFiles", title: "采购商其他要求(附件)", type: "html",
formatter: (val = [], row, column, index) => {
return formatPreviewLinks(val)
}
},
{
key: "addressRegion", title: "加工交货地址", type: "text",
formatter: (val = [], row, column, index) => {
return `${val.province.name} ${val.city.name} ${val.area.name} ${row.addressDetail}`
}
},
{
key: "invoice", title: "是否含税", type: "radio", data: [
{label: "含税", value: true},
{label: "不含税", value: false}
]
},
{
key: "writeInvoiceTime", title: "开票时间", type: "radio", data: [
{label: "付款当月(限20号之前付款,20号之后付款次月开票)", value: 0},
{label: "付款后次月", value: 1},
{label: "付款前", value: 2}
]
},
// {
// key: "invoiceType", title: "发票种类", type: "radio", data: [
// {label: "增值税专用发票13%", value: 0},
// {label: "增值税普通发票", value: 1},
// {label: "普通发票", value: 2}
// ]
// },
// {key: "invoiceOther", title: "发票其他要求", type: "text"},
{
key: "taxType", title: "纳税人身份", type: "text", showRule: formData => {
return !!formData.invoiceOther
}
},
{
key: "invoiceType", title: "发票种类", type: "text", showRule: formData => {
return !!formData.invoiceOther
}
},
{
key: "taxRate", title: "税率", type: "text", showRule: formData => {
return !!formData.invoiceOther
}
},
{
key: "invoiceOther", title: "手动填写税票要求", type: "text", showRule: formData => {
console.log(formData)
return !!formData.taxType
}
},
{key: "transportDocuments", title: "随货资料", type: "text"},
{key: "otherTransportDocuments", title: "运输其他要求", type: "text"},
{
key: "transportLimit", title: "运输限制", type: "radio", data: [
{label: "有", value: true},
{label: "无", value: false}
]
},
{
key: "tradeMethod", title: "交易模式", type: "radio", data: [
{label: "自主交易", value: 0},
{label: "金久信公证", value: 1},
]
},
{
key: "payMethod", title: "付款方式", type: "radio", data: [
{label: "预付", value: 0},
{label: "加工验收合格后付全款", value: 1},
// {label: "提货付全款", value: 2},
{label: "加工验收合格后X天内支付全款", value: 3},
{label: "其他付款方式", value: 4},
]
},
{key: "advancePayRate", title: "预付比例(%)", type: "text"},
{key: "reputationPayDay", title: "账期天数", type: "text"},
{key: "otherPayMethod", title: "其他付款方式", type: "text"},
{
key: "offerType", title: "报价形式", type: "radio", data: [
{label: "整单报价", value: 0},
{label: "可分项报价", value: 1}
]
},
{
key: "answerStartTime", title: "报价时限(开始)", type: "time"
},
{
key: "answerEndTime", title: "报价时限(结束)", type: "time"
},
{key: "earnestMoney", title: "交保证金要求", type: "text",
formatter: (val, row, column, index) => {
return val === 'NaN' ? '' : val
}},
{
key: "signMethod", title: "签约模式", type: "radio", data: [
{label: "线上签约-标准合同", value: 0},
{label: "线下签约", value: 1},
{label: "线上签约-双方协商合同", value: 2},
]
},
{
key: "contract", title: "合同文件", type: "html",
formatter: (val = [], row, column, index) => {
return formatPreviewLinks(row.contract && row.contract.contractBase)
},
showRule: formData => {
return formData.signMethod === 2
}
},
{key: "supplementary", title: "采购商补充条款", type: "text"},
{key: "companyName", title: "公司信息", type: "text"},
{key: "companyMobile", title: "公司联系方式", type: "text"},
{key: "businessName", title: "授权业务咨询人", type: "text"},
{key: "businessMobile", title: "业务咨询联系方式", type: "text"},
],
// 页面是否请求中或加载中
loading: false,
// init请求返回的数据
data: {},
// 表格相关开始 -----------------------------------------------------------
table1: {
// 表格数据请求地址
action: "admin/process/sys/getList",
// 表格字段显示规则
columns: [
{
key: "title",
title: "标题",
type: "text",
align: "left",
width: 200
},
{
key: "num",
title: "加工量",
type: "text",
align: "left",
},
{
key: "",
title: "采购企业",
type: "text",
align: "left",
width: 220,
formatter: (val = [], row, column, index) => {
return row.user.accountType === 1 ? row.user.person.personName : row.user.company.companyName;
}
},
{
key: "",
title: "报价情况",
type: "text",
align: "left",
formatter: (val = [], row, column, index) => {
return `${row.quoteNum}家`
}
},
{
key: "status",
title: "状态",
type: "tag",
data: [
{value: 0, label: '待选商', tagType: 'warning'},
{value: 1, label: '已选商', tagType: 'danger'},
{value: 2, label: '已完成', tagType: 'success'},
]
},
{
key: "orderAmount",
title: "订单金额",
type: "html",
width: 200
},
{key: "isShow", title: "是否显示", type: "html"},
{key: "quoteAmount", title: "单次报价金额", type: "html", width: 210,},
{
key: "_add_time",
title: "发布时间",
type: "time",
align: "left",
width: 160,
sortable: "custom"
},
{
key: "_add_time_diff",
title: "距离现在",
type: "html",
align: "left",
width: 120,
formatter: (val, row) => vk.pubfn.dateDiff(row._add_time)
},
{
key: "action", title: "操作", type: "html",
width: 380
},
],
// 多选框选中的值
multipleSelection: [],
// 当前高亮的记录
selectItem: ""
},
// 表格相关结束 -----------------------------------------------------------
// 表单相关开始 -----------------------------------------------------------
// 查询表单请求数据
queryForm1: {
// 查询表单数据源,可在此设置默认值
formData: {},
// 查询表单的字段规则 fieldName:指定数据库字段名,不填默认等于key
columns: [
{
key: "title",
title: "标题",
type: "text",
width: 160,
mode: "%%"
},
{
key: "status",
title: "选商状态",
type: "select",
data: [
{value: 0, label: '未选商'},
{value: 1, label: '已选商'},
{value: 2, label: '已完成'},
]
},
{
key: "showInAdmin",
title: "删除状态",
type: "select",
data: [
{value: 1, label: '未删除'},
{value: 0, label: '已删除'},
]
},
{
key: "signMethod",
title: "签约方式",
type: "select",
data: [
{value: 0, label: '线上签约-标准合同'},
{value: 1, label: '线下签约'},
{value: 2, label: '线上签约-双方协商合同'},
]
},
// {
// key: "_add_time",
// title: "添加时间",
// type: "datetimerange",
// width: 400,
// mode: "[]"
// },
]
},
form1: {
// 表单请求数据,此处可以设置默认值
data: {
sort: 0
},
// 表单属性
props: {
// 表单请求地址
action: "",
// 表单字段显示规则
columns: [{
key: "name",
title: "名称",
type: "text",
placeholder: "请输入分类名称"
},
{
key: "icon",
title: "图标",
type: "icon",
placeholder: "请选择图标"
},
{
key: "parent_id",
title: "上级分类",
type: "tree-select",
placeholder: "请选择上级分类",
action: "admin/spot/category/sys/getTree",
props: {
list: "rows",
value: "_id",
label: "name",
children: "children"
},
},
{
key: "remark",
title: "备注",
type: "textarea",
maxlength: "99",
showWordLimit: true,
autosize: {
minRows: 2,
maxRows: 10
},
},
{
key: "sort",
title: "排序",
type: "number",
precision: 0,
placeholder: "请输入排序值",
},
],
// 表单验证规则
rules: {
sort: [{
type: 'number',
message: '排序值必须为数字'
}],
name: [
{required: true, message: '分类名称不能为空', trigger: 'blur'},
],
},
// add 代表添加 update 代表修改
formType: "",
// 是否显示表单的弹窗
show: false
}
},
// 其他弹窗表单
formDatas: {},
// 表单相关结束 -----------------------------------------------------------
};
},
// 监听 - 页面每次【加载时】执行(如:前进)
onLoad(options = {}) {
that = this;
vk = that.vk;
that.options = options;
that.registerFilePreviewHandler();
that.init(options);
},
onUnload() {
this.unregisterFilePreviewHandler();
},
beforeDestroy() {
this.unregisterFilePreviewHandler();
this.revokePdfPreviewUrl();
},
// 监听 - 页面【首次渲染完成时】执行。注意如果渲染速度快,会在页面进入动画完成前触发
onReady() {
},
// 监听 - 页面每次【显示时】执行(如:前进和返回) (页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面)
onShow() {
},
// 监听 - 页面每次【隐藏时】执行(如:返回)
onHide() {
},
// 函数
methods: {
// 页面数据初始化函数
init(options) {
originalForms["form1"] = vk.pubfn.copyObject(that.form1);
},
registerFilePreviewHandler() {
if (typeof window === "undefined") return
window.__previewProcessFile = encodedUrl => {
this.previewFile(decodeURIComponent(encodedUrl))
}
},
unregisterFilePreviewHandler() {
if (typeof window === "undefined") return
if (window.__previewProcessFile) delete window.__previewProcessFile
},
// 页面跳转
pageTo(path) {
vk.navigateTo(path);
},
// 表单重置
resetForm() {
vk.pubfn.resetForm(originalForms, that);
},
// 搜索
search() {
that.$refs.table1.search();
},
// 刷新
refresh() {
that.$refs.table1.refresh();
},
// 获取当前选中的行的数据
getCurrentRow() {
return that.$refs.table1.getCurrentRow();
},
// 监听 - 行的选中高亮事件
currentChange(val) {
that.table1.selectItem = val;
},
// 当选择项发生变化时会触发该事件
selectionChange(list) {
that.table1.multipleSelection = list;
},
// 显示添加页面
addBtn() {
that.resetForm();
that.form1.props.action = 'admin/contract/template/sys/add';
that.form1.props.formType = 'add';
that.form1.props.title = '添加';
that.form1.props.show = true;
},
// 显示修改页面
updateBtn({
item
}) {
that.form1.props.action = 'admin/contract/template/sys/update';
that.form1.props.formType = 'update';
that.form1.props.title = '编辑';
that.form1.props.show = true;
that.form1.data = item;
},
// 删除按钮
deleteBtn({
item,
deleteFn
}) {
deleteFn({
action: "admin/contract/template/sys/delete",
data: {
_id: item._id
},
});
},
// 监听 - 批量操作的按钮点击事件
batchBtn(index) {
switch (index) {
case 1:
vk.toast("批量操作按钮1");
break;
case 2:
vk.toast("批量操作按钮2");
break;
default:
break;
}
},
changeField(id, field, value) {
vk.callFunction({
url: 'admin/process/sys/changeField',
data: {
id, field, value
}
}).then(() => {
this.$refs.table1.refresh()
})
},
doShowInfo(info) {
this.info = info
this.title = '详情'
this.showInfo = true
},
showQuoteList({_id}) {
this.$refs.ProcessQuoteList.open(_id)
},
changeQuoteAmount(value, id) {
this.changeField(id, 'quoteAmount', value)
},
showPayList(row) {
this.$refs.PayList.open(row.payList)
},
getFileExt(url = "") {
const cleanUrl = String(url).split("?")[0].split("#")[0]
const match = cleanUrl.match(/\.([a-z0-9]+)$/i)
return match ? match[1].toLowerCase() : ""
},
isImageFile(url) {
return ["png", "jpg", "jpeg", "gif", "webp", "bmp", "svg"].includes(this.getFileExt(url))
},
isPdfFile(url) {
return this.getFileExt(url) === "pdf"
},
isOfficeFile(url) {
return ["doc", "docx", "xls", "xlsx", "ppt", "pptx"].includes(this.getFileExt(url))
},
getOfficePreviewUrl(url) {
return `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(url)}`
},
revokePdfPreviewUrl() {
if (this.pdfObjectUrl) {
URL.revokeObjectURL(this.pdfObjectUrl)
this.pdfObjectUrl = ''
}
this.pdfPreviewUrl = ''
},
async previewPdfFile(url) {
this.revokePdfPreviewUrl()
try {
const response = await fetch(url)
if (!response.ok) throw new Error('PDF加载失败')
const blob = await response.blob()
this.pdfObjectUrl = URL.createObjectURL(new Blob([blob], {type: 'application/pdf'}))
this.pdfPreviewUrl = this.pdfObjectUrl
} catch (e) {
this.pdfPreviewUrl = `https://mozilla.github.io/pdf.js/web/viewer.html?file=${encodeURIComponent(url)}`
}
this.showPdfPreview = true
},
previewFile(url) {
if (!url) return
if (this.isImageFile(url)) {
this.previewImageUrl = url
this.showImagePreview = true
return
}
if (this.isPdfFile(url)) {
this.previewPdfFile(url)
return
}
if (this.isOfficeFile(url)) {
window.open(this.getOfficePreviewUrl(url), "_blank")
return
}
window.open(url, "_blank")
},
},
// 监听属性
watch: {},
// 过滤器
filters: {},
// 计算属性
computed: {}
};
</script>
<style lang="scss" scoped>
.page-body {
}
.preview-image {
display: block;
max-width: 100%;
max-height: 75vh;
margin: 0 auto;
}
.pdf-preview-frame {
display: block;
width: 100%;
height: 75vh;
border: 0;
}
</style>
+454
View File
@@ -0,0 +1,454 @@
<template>
<view class="page-body">
<!-- 页面内容开始 -->
<!-- 表格搜索组件开始 -->
<vk-data-table-query v-model="queryForm1.formData" :columns="queryForm1.columns"
@search="search"></vk-data-table-query>
<!-- 表格搜索组件结束 -->
<!-- 自定义按钮区域开始 -->
<view>
<el-row>
</el-row>
</view>
<!-- 自定义按钮区域结束 -->
<!-- 表格组件开始 -->
<vk-data-table ref="table1" :action="table1.action" :columns="table1.columns" :query-form-param="queryForm1"
:pagination="true" @current-change="currentChange"
>
<template v-slot:action="{ row, column, index }">
<template v-if="row.orderStatus === 5">
<el-button type="success" size="mini" @click.native="refundPass(row)">通过</el-button>
<el-button type="danger" size="mini" @click.native="refundRefuse(row)">拒绝</el-button>
</template>
</template>
<template v-slot:goods="{ row, column, index }">
<div v-for="(item, index) in row.goods" :key="index">
<p>商品名称: {{ item.goodsName }}</p>
<p>数量: {{ item.num }}</p>
<p>单价: {{ item.goodsPrice }}</p>
<el-divider v-if="index < row.goods.length - 1"/>
</div>
</template>
</vk-data-table>
<!-- 表格组件结束 -->
<!-- 添加或编辑的弹窗开始 -->
<vk-data-dialog v-model="form1.props.show" :title="form1.props.title" width="60%" mode="form"
:close-on-click-modal="false">
<vk-data-form v-model="form1.data" :rules="form1.props.rules" :action="form1.props.action"
:form-type="form1.props.formType" :columns='form1.props.columns' label-width="120px"
@success="form1.props.show = false;refresh();"></vk-data-form>
</vk-data-dialog>
<!-- 添加或编辑的弹窗结束 -->
<!-- 页面内容结束 -->
</view>
</template>
<script>
var that; // 当前页面对象
var vk = uni.vk; // vk实例
var originalForms = {}; // 表单初始化数据
export default {
data() {
// 页面数据变量
return {
showInfo: false,
info: null,
title: '',
infoColumns: [],
// 页面是否请求中或加载中
loading: false,
// init请求返回的数据
data: {},
// 表格相关开始 -----------------------------------------------------------
table1: {
// 表格数据请求地址
action: "admin/order/sys/getList",
// 表格字段显示规则
columns: [
{
key: "orderNo",
title: "订单号",
type: "text",
},
{
key: "type",
title: "订单类型",
type: "select",
align: "center",
data: [
{value: 0, label: '商城订单'},
{value: 1, label: '金久信自营订单'},
{value: 2, label: '保证金'},
{value: 3, label: '会员升级'},
{value: 4, label: '询价订单'},
{value: 5, label: '加工订单'},
{value: 6, label: '旧货订单'},
]
},
{
key: "amount",
title: "订单金额",
type: "html",
formatter: (val = [], row, column, index) => {
let content = `<div>订单金额:¥` + row.amount + `</div>`
content += `<div>应付金额:¥${row.offAmount}</div>`
if (row.type < 4 && row.payAmount) {
content += `<div>实付金额:¥${row.payAmount ? row.payAmount : ''}</div>`
}
return content
}
},
{
key: "orderStatus",
title: "订单状态",
type: "text",
align: "center",
formatter: (val = [], row, column, index) => {
const orderStatusList = [
'待支付',
'待发货',
'待收货',
'待完成',
'已完成',
'退款审核中',
'退款成功',
'退款失败',
]
let str = orderStatusList[val]
if (val === 7) str += `: ${row.refundRefuseReason}`
return str
}
},
{
key: "user",
title: "买方",
type: "html",
formatter: (val = [], row, column, index) => {
let content = `<div>` + val.mobile + `</div>`
content += `<div>` + val.accountType === 2 ? val.company.companyName : val.person.personName + `</div>`
return content
}
},
{
key: "goods",
title: "商品列表",
type: "html",
},
{
key: "refundReason",
title: "申请原因",
type: "text",
},
{
key: "refundPhotos",
title: "用户附件",
type: "image",
},
{
key: "refundRequestAt",
title: "申请时间",
type: "text",
align: "left",
width: 160,
sortable: "custom"
},
{
key: "action",
title: "操作",
type: "html",
}
],
// 多选框选中的值
multipleSelection: [],
// 当前高亮的记录
selectItem: ""
},
// 表格相关结束 -----------------------------------------------------------
// 表单相关开始 -----------------------------------------------------------
// 查询表单请求数据
queryForm1: {
// 查询表单数据源,可在此设置默认值
formData: {
orderStatus: [5, 6, 7]
},
// 查询表单的字段规则 fieldName:指定数据库字段名,不填默认等于key
columns: [
{
key: "orderNo",
title: "订单号",
type: "text",
width: 160,
mode: "%%"
},
{
key: "type",
title: "订单类型",
type: "select",
align: "center",
data: [
{value: 0, label: '商城订单'},
{value: 1, label: '金久信自营订单'},
{value: 2, label: '保证金'},
{value: 3, label: '会员升级'},
{value: 4, label: '询价订单'},
{value: 5, label: '加工订单'},
{value: 6, label: '旧货订单'},
]
},
// {
// key: "orderStatus",
// title: "退款状态",
// type: "select",
// align: "center",
// data: [
// {value: [5,6,7], label: '全部状态'},
// {value: 5, label: '待审核'},
// {value: 6, label: '退款成功'},
// {value: 7, label: '退款拒绝'},
// ]
// },
// {
// key: "_add_time",
// title: "下单时间",
// type: "datetimerange",
// width: 400,
// mode: "[]"
// },
]
},
form1: {
// 表单请求数据,此处可以设置默认值
data: {
sort: 0
},
// 表单属性
props: {
// 表单请求地址
action: "",
// 表单字段显示规则
columns: [
{
key: "orderNo",
title: "订单号",
type: "text",
placeholder: "请输入分类名称"
},
{
key: "icon",
title: "图标",
type: "icon",
placeholder: "请选择图标"
},
{
key: "parent_id",
title: "上级分类",
type: "tree-select",
placeholder: "请选择上级分类",
action: "admin/spot/category/sys/getTree",
props: {
list: "rows",
value: "_id",
label: "name",
children: "children"
},
},
{
key: "remark",
title: "备注",
type: "textarea",
maxlength: "99",
showWordLimit: true,
autosize: {
minRows: 2,
maxRows: 10
},
},
{
key: "sort",
title: "排序",
type: "number",
precision: 0,
placeholder: "请输入排序值",
},
],
// 表单验证规则
rules: {
sort: [{
type: 'number',
message: '排序值必须为数字'
}],
name: [
{required: true, message: '分类名称不能为空', trigger: 'blur'},
],
},
// add 代表添加 update 代表修改
formType: "",
// 是否显示表单的弹窗
show: false
}
},
// 其他弹窗表单
formDatas: {},
// 表单相关结束 -----------------------------------------------------------
};
},
// 监听 - 页面每次【加载时】执行(如:前进)
onLoad(options = {}) {
that = this;
vk = that.vk;
that.options = options;
that.init(options);
},
// 监听 - 页面【首次渲染完成时】执行。注意如果渲染速度快,会在页面进入动画完成前触发
onReady() {
},
// 监听 - 页面每次【显示时】执行(如:前进和返回) (页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面)
onShow() {
},
// 监听 - 页面每次【隐藏时】执行(如:返回)
onHide() {
},
// 函数
methods: {
// 页面数据初始化函数
init(options) {
originalForms["form1"] = vk.pubfn.copyObject(that.form1);
},
// 页面跳转
pageTo(path) {
vk.navigateTo(path);
},
// 表单重置
resetForm() {
vk.pubfn.resetForm(originalForms, that);
},
// 搜索
search() {
if (!that.queryForm1.formData.orderStatus) {
that.queryForm1.formData.orderStatus = [5,6,7]
}
that.$refs.table1.search();
},
// 刷新
refresh() {
that.$refs.table1.refresh();
},
// 获取当前选中的行的数据
getCurrentRow() {
return that.$refs.table1.getCurrentRow();
},
// 监听 - 行的选中高亮事件
currentChange(val) {
that.table1.selectItem = val;
},
// 当选择项发生变化时会触发该事件
selectionChange(list) {
that.table1.multipleSelection = list;
},
// 显示添加页面
addBtn() {
that.resetForm();
that.form1.props.action = 'admin/contract/template/sys/add';
that.form1.props.formType = 'add';
that.form1.props.title = '添加';
that.form1.props.show = true;
},
// 显示修改页面
updateBtn({
item
}) {
that.form1.props.action = 'admin/contract/template/sys/update';
that.form1.props.formType = 'update';
that.form1.props.title = '编辑';
that.form1.props.show = true;
that.form1.data = item;
},
// 删除按钮
deleteBtn({
item,
deleteFn
}) {
deleteFn({
action: "admin/contract/template/sys/delete",
data: {
_id: item._id
},
});
},
// 监听 - 批量操作的按钮点击事件
batchBtn(index) {
switch (index) {
case 1:
vk.toast("批量操作按钮1");
break;
case 2:
vk.toast("批量操作按钮2");
break;
default:
break;
}
},
changeField(id, field, value) {
vk.callFunction({
url: 'admin/old/sys/changeField',
data: {
id, field, value
}
}).then(() => {
this.$refs.table1.refresh()
})
},
doShowInfo(info) {
this.info = info
this.title = '详情'
this.showInfo = true
},
async refundPass({_id}) {
await vk.callFunction({
url: 'admin/order/sys/refund',
data: {
id: _id,
orderStatus: 6
}
})
this.$message.success('操作成功')
this.$refs.table1.refresh()
},
async refundRefuse({_id}) {
const {action, value} = await this.$prompt('拒绝理由', {
showInput: true
});
if (action === 'confirm') {
await vk.callFunction({
url: 'admin/order/sys/refund',
data: {
id: _id,
orderStatus: 7,
refundRefuseReason: value
}
})
this.$message.success('操作成功')
this.$refs.table1.refresh()
}
},
},
// 监听属性
watch: {},
// 过滤器
filters: {},
// 计算属性
computed: {}
};
</script>
<style lang="scss" scoped>
.page-body {
}
</style>
@@ -0,0 +1,119 @@
<template>
<div>
<el-table :data="list" style="width: 100%">
<el-table-column prop="user.company.companyName" label="企业"/>
<el-table-column prop="desc" label="产品描述"/>
<el-table-column prop="amount" label="报价"/>
<el-table-column label="附件">
<template v-slot="{ row }">
<p v-for="(item, index) in row.files" :key="index">
<a :href="item" target="_blank">预览:文件{{ index + 1 }}</a>
</p>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注"/>
<el-table-column label="状态">
<template v-slot="{ row }">
<span v-if="row.status === 0">待选商</span>
<span v-if="row.status === 1">已选</span>
</template>
</el-table-column>
<el-table-column label="操作">
<template v-slot="{ row }">
<el-button type="primary" size="small" v-if="info.status === 1" @click="edit(row)" plain>编辑</el-button>
<el-button type="primary" size="small" v-if="info.status === 1" :disabled="!row.amount" @click="confirm(row._id)">选商
</el-button>
</template>
</el-table-column>
</el-table>
<div style="margin-top: 2rem; text-align: center">
<el-button plain @click.native="cancel">关闭</el-button>
</div>
<el-dialog title="编辑报价" :visible.sync="dialogVisible" width="50%" append-to-body>
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="报价">
<el-input v-model="form.amount" placeholder="请输入报价"/>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="form.remark" placeholder="请输入备注"/>
</el-form-item>
<el-form-item label="附件">
<vk-data-upload accept="*" list-type="text" v-model="form.files"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doEdit">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "SelectQuote",
props: {
info: {
type: Object
}
},
data() {
return {
list: [],
clickedInfo: null,
dialogVisible: null,
form: {
_id: null,
amount: null,
remark: null,
files: [],
}
}
},
methods: {
async getList() {
const {rows} = await vk.callFunction({
url: 'admin/selfProduct/quote/sys/getQuoteList',
data: {pageSize: 500, quoteId: this.info._id}
})
this.list = rows
},
cancel() {
this.$emit('cancel')
},
async confirm(quoteId) {
await vk.callFunction({
url: 'admin/selfProduct/quote/sys/confirmQuote',
data: {
quoteId,
sheetId: this.info._id
}
})
this.cancel()
},
edit(info) {
this.form = {
_id: info._id,
amount: info.amount,
remark: info.remark,
files: info.files ?? []
}
this.dialogVisible = true
},
doEdit(){
vk.callFunction({
url: 'admin/selfProduct/quote/sys/editQuote',
data: this.form
}).then(() => {
this.dialogVisible = false
this.getList()
})
}
},
mounted() {
this.getList()
}
}
</script>
@@ -0,0 +1,68 @@
<template>
<div>
<p>公司选择:</p>
<el-select v-model="selectedList" placeholder="点击选择报价公司" style="margin-top: 1rem; width: 90%" multiple clearable filterable>
<el-option
v-for="(item, index) in companyList"
:key="item.value"
:label="item.nickname"
:value="item._id">
</el-option>
</el-select>
<p style="margin-top: 2rem;">产品描述:</p>
<el-input type="textarea" v-model="desc" placeholder="请输入" style="margin-top: 1rem; width: 90%"></el-input>
<div style="margin-top: 2rem; text-align: center">
<el-button plain @click.native="cancel">取消</el-button>
<el-button type="primary" :disabled="selectedList.length === 0" @click.native="confirm">确定</el-button>
</div>
</div>
</template>
<script>
export default {
name: "SetEnquiry",
props: {
info: {
type: Object
}
},
data() {
return {
selectedList: [],
companyList: [],
desc: ''
}
},
methods: {
async getCompanyList() {
const {rows} = await vk.callFunction({
url: 'admin/system/user/sys/getList',
data: {type: 2, pageSize: 500}
// data: {pageSize: 500}
})
// this.companyList = rows.filter(item => item.company && item.company.companyName !== '' && item.company.companyName)
this.companyList = rows
},
cancel(){
this.$emit('cancel')
},
async confirm(){
await vk.callFunction({
url: 'admin/selfProduct/quote/sys/setCompany',
data: {
list: this.selectedList,
quoteId: this.info._id,
desc: this.desc,
}
})
this.cancel()
}
},
mounted() {
this.desc = this.info.desc
this.getCompanyList()
}
}
</script>
+418
View File
@@ -0,0 +1,418 @@
<template>
<view class="page-body">
<!-- 页面内容开始 -->
<!-- 表格搜索组件开始 -->
<vk-data-table-query v-model="queryForm1.formData" :columns="queryForm1.columns"
@search="search"></vk-data-table-query>
<!-- 表格搜索组件结束 -->
<!-- 自定义按钮区域开始 -->
<view>
<el-row>
</el-row>
</view>
<!-- 自定义按钮区域结束 -->
<!-- 表格组件开始 -->
<vk-data-table ref="table1" :action="table1.action" :columns="table1.columns" :query-form-param="queryForm1"
:pagination="true" @current-change="currentChange"
>
<template v-slot:action="{ row, column, index }">
<el-button size="mini" @click.native="setEnquiry(row)" v-if="[0, 1].includes(row.status)">询价</el-button>
<el-button size="mini" @click.native="selectQuote(row)" v-if="row.status === 1" type="success">选商</el-button>
<el-button size="mini" @click.native="selectQuote(row)" v-if="row.status === 2" type="success">报价列表</el-button>
<el-button size="mini" @click.native="showPayList(row)" v-if="row.payList">支付明细</el-button>
</template>
<template v-slot:orderAmount="{ row, column, index }">
<p v-if="row.quote && row.quote.amount">报价金额: ¥{{ row.quote.amount }}</p>
<p v-if="row.payList">实付金额: ¥{{
row.payList.reduce((pre, cur) => (cur.hasPaid && !cur.buyerRefuse && cur.sellerConfirm) ? parseFloat(pre) + parseFloat(cur.amount) : pre, 0)
}}</p>
</template>
</vk-data-table>
<!-- 表格组件结束 -->
<!-- 添加或编辑的弹窗开始 -->
<vk-data-dialog v-model="form1.props.show" :title="form1.props.title" width="60%" mode="form"
:close-on-click-modal="false">
<vk-data-form v-model="form1.data" :rules="form1.props.rules" :action="form1.props.action"
:form-type="form1.props.formType" :columns='form1.props.columns' label-width="120px"
@success="form1.props.show = false;refresh();"></vk-data-form>
</vk-data-dialog>
<!-- 添加或编辑的弹窗结束 -->
<!-- 页面内容结束 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="70%">
<set-enquiry v-if="dialogVisible && dialogType === 'set-enquiry'" :info="clickInfo" @cancel="closeDialog"/>
<select-quote v-if="dialogVisible && dialogType === 'select-quote'" :info="clickInfo" @cancel="closeDialog"/>
</el-dialog>
<PayList ref="PayList"/>
</view>
</template>
<script>
import SetExpress from "../components/setExpress.vue";
import SelfProductInfo from "../components/selfProductInfo.vue";
import SetEnquiry from "./components/SetEnquiry.vue";
import SelectQuote from "./components/SelectQuote.vue";
import PayList from "../components/PayList.vue";
var that; // 当前页面对象
var vk = uni.vk; // vk实例
var originalForms = {}; // 表单初始化数据
export default {
components: {PayList, SelectQuote, SetEnquiry, SelfProductInfo, SetExpress},
data() {
// 页面数据变量
return {
dialogTitle: null,
dialogType: null,
dialogVisible: false,
clickInfo: null,
showInfo: false,
info: null,
title: '',
// 页面是否请求中或加载中
loading: false,
// init请求返回的数据
data: {},
// 表格相关开始 -----------------------------------------------------------
table1: {
// 表格数据请求地址
action: "admin/selfProduct/quote/sys/getList",
// 表格字段显示规则
columns: [
{
key: "",
title: "询价地区",
type: "text",
align: "left",
formatter: (val = [], row, column, index) => {
return `${row.province.name}${row.city.name}`;
}
},
{
key: "name",
title: "联系人",
type: "text",
align: "center",
},
{
key: "phone",
title: "联系方式",
type: "text",
align: "center",
},
{
key: "company",
title: "公司名称",
type: "text",
align: "center",
},
{
key: "status",
title: "状态",
type: "select",
align: "center",
data: [
{value: 0, label: '待操作'},
{value: 1, label: '待选商'},
{value: 2, label: '已选商'},
]
},
{
key: "orderAmount",
title: "订单金额",
type: "html",
},
{
key: "files", title: "附件", type: "html",
formatter: (val = [], row, column, index) => {
let content = ''
val.forEach((item, itemIndex) => {
content += `<a href="${item}" target="_blank">预览:文件${itemIndex + 1}</a> `
})
return content
}
},
{
key: "_add_time",
title: "添加时间",
type: "time",
align: "left",
width: 160,
sortable: "custom"
},
{
key: "_add_time_diff",
title: "距离现在",
type: "html",
align: "left",
width: 120,
formatter: (val, row) => vk.pubfn.dateDiff(row._add_time)
},
{key: "action", title: "操作", type: "html", width: 240},
],
// 多选框选中的值
multipleSelection: [],
// 当前高亮的记录
selectItem: ""
},
// 表格相关结束 -----------------------------------------------------------
// 表单相关开始 -----------------------------------------------------------
// 查询表单请求数据
queryForm1: {
// 查询表单数据源,可在此设置默认值
formData: {},
// 查询表单的字段规则 fieldName:指定数据库字段名,不填默认等于key
columns: [
{
key: "address",
title: "询价地区",
type: "address",
align: "left",
level: 2
},
// {
// key: "name",
// title: "名称",
// type: "text",
// width: 160,
// mode: "%%"
// },
// {
// key: "remark",
// title: "备注",
// type: "text",
// width: 160,
// mode: "%%"
// },
// {
// key: "_add_time",
// title: "添加时间",
// type: "datetimerange",
// width: 400,
// mode: "[]"
// },
]
},
form1: {
// 表单请求数据,此处可以设置默认值
data: {
sort: 0
},
// 表单属性
props: {
// 表单请求地址
action: "",
// 表单字段显示规则
columns: [{
key: "name",
title: "名称",
type: "text",
placeholder: "请输入分类名称"
},
{
key: "icon",
title: "图标",
type: "icon",
placeholder: "请选择图标"
},
{
key: "parent_id",
title: "上级分类",
type: "tree-select",
placeholder: "请选择上级分类",
action: "admin/spot/category/sys/getTree",
props: {
list: "rows",
value: "_id",
label: "name",
children: "children"
},
},
{
key: "remark",
title: "备注",
type: "textarea",
maxlength: "99",
showWordLimit: true,
autosize: {
minRows: 2,
maxRows: 10
},
},
{
key: "sort",
title: "排序",
type: "number",
precision: 0,
placeholder: "请输入排序值",
},
],
// 表单验证规则
rules: {
sort: [{
type: 'number',
message: '排序值必须为数字'
}],
name: [
{required: true, message: '分类名称不能为空', trigger: 'blur'},
],
},
// add 代表添加 update 代表修改
formType: "",
// 是否显示表单的弹窗
show: false
}
},
// 其他弹窗表单
formDatas: {},
// 表单相关结束 -----------------------------------------------------------
};
},
// 监听 - 页面每次【加载时】执行(如:前进)
onLoad(options = {}) {
that = this;
vk = that.vk;
that.options = options;
that.init(options);
},
// 监听 - 页面【首次渲染完成时】执行。注意如果渲染速度快,会在页面进入动画完成前触发
onReady() {
},
// 监听 - 页面每次【显示时】执行(如:前进和返回) (页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面)
onShow() {
},
// 监听 - 页面每次【隐藏时】执行(如:返回)
onHide() {
},
// 函数
methods: {
// 页面数据初始化函数
init(options) {
originalForms["form1"] = vk.pubfn.copyObject(that.form1);
},
// 页面跳转
pageTo(path) {
vk.navigateTo(path);
},
// 表单重置
resetForm() {
vk.pubfn.resetForm(originalForms, that);
},
// 搜索
search() {
that.$refs.table1.search();
},
// 刷新
refresh() {
that.$refs.table1.refresh();
},
// 获取当前选中的行的数据
getCurrentRow() {
return that.$refs.table1.getCurrentRow();
},
// 监听 - 行的选中高亮事件
currentChange(val) {
that.table1.selectItem = val;
},
// 当选择项发生变化时会触发该事件
selectionChange(list) {
that.table1.multipleSelection = list;
},
// 显示添加页面
addBtn() {
that.resetForm();
that.form1.props.action = 'admin/contract/template/sys/add';
that.form1.props.formType = 'add';
that.form1.props.title = '添加';
that.form1.props.show = true;
},
// 显示修改页面
updateBtn({
item
}) {
that.form1.props.action = 'admin/contract/template/sys/update';
that.form1.props.formType = 'update';
that.form1.props.title = '编辑';
that.form1.props.show = true;
that.form1.data = item;
},
// 删除按钮
deleteBtn({
item,
deleteFn
}) {
deleteFn({
action: "admin/contract/template/sys/delete",
data: {
_id: item._id
},
});
},
// 监听 - 批量操作的按钮点击事件
batchBtn(index) {
switch (index) {
case 1:
vk.toast("批量操作按钮1");
break;
case 2:
vk.toast("批量操作按钮2");
break;
default:
break;
}
},
changeField(id, field, value) {
vk.callFunction({
url: 'admin/old/sys/changeField',
data: {
id, field, value
}
}).then(() => {
this.$refs.table1.refresh()
})
},
doShowInfo(info) {
this.info = info
this.dialogTitle = '详情'
this.showInfo = true
},
setEnquiry(info) {
this.clickInfo = info
this.dialogType = 'set-enquiry'
this.dialogTitle = '询价'
this.dialogVisible = true
},
selectQuote(info) {
this.clickInfo = info
this.dialogType = 'select-quote'
this.dialogTitle = '选商'
this.dialogVisible = true
},
closeDialog(){
this.dialogVisible = false
this.$refs.table1.refresh()
},
showPayList(row) {
this.$refs.PayList.open(row.payList)
},
},
// 监听属性
watch: {},
// 过滤器
filters: {},
// 计算属性
computed: {}
};
</script>
<style lang="scss" scoped>
.page-body {
}
</style>
+476
View File
@@ -0,0 +1,476 @@
<template>
<view class="page-body">
<!-- 页面内容开始 -->
<!-- 表格搜索组件开始 -->
<vk-data-table-query v-model="queryForm1.formData" :columns="queryForm1.columns"
@search="search"></vk-data-table-query>
<!-- 表格搜索组件结束 -->
<!-- 自定义按钮区域开始 -->
<view>
<el-row>
</el-row>
</view>
<!-- 自定义按钮区域结束 -->
<!-- 表格组件开始 -->
<vk-data-table ref="table1" :action="table1.action" :columns="table1.columns" :query-form-param="queryForm1"
:pagination="true" @current-change="currentChange"
>
<template v-slot:action="{ row, column, index }">
<template v-if="row.orderStatus === 1">
<el-button type="success" size="mini" @click.native="setExpress(row)">派单</el-button>
</template>
<template v-if="row.type === 1">
<el-button size="mini" plain @click.native="showSelfProductInfo(row)">详情</el-button>
</template>
<template v-if="row.orderStatus === 10">
<el-button size="mini" type="success" @click.native="setPrice(row)">报价</el-button>
</template>
</template>
<template v-slot:goods="{ row, column, index }">
<div v-for="(item, index) in row.goods" :key="index" style="
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;">
<p>商品名称: {{ item.goodsName }}</p>
<p>数量: {{ item.num }}</p>
<p v-if="row.orderStatus !== 10">单价: {{ item.goodsPrice }}</p>
<template v-if="row.subType === 2 && item.amountItem">
<p>项基础收费: {{ item.amountItem.amount }}元</p>
<p v-if="item.costNum">清单单品项数: {{ item.costNum }}</p>
<p>项数加价: {{ item.amountItem.addAmount }}元</p>
<p>建议收费: {{ item.amountItem.amount + (item.costNum * item.amountItem.addAmount) }}元</p>
</template>
<el-divider v-if="index < row.goods.length - 1"/>
</div>
</template>
</vk-data-table>
<!-- 表格组件结束 -->
<!-- 添加或编辑的弹窗开始 -->
<vk-data-dialog v-model="form1.props.show" :title="form1.props.title" width="60%" mode="form"
:close-on-click-modal="false">
<vk-data-form v-model="form1.data" :rules="form1.props.rules" :action="form1.props.action"
:form-type="form1.props.formType" :columns='form1.props.columns' label-width="120px"
@success="form1.props.show = false;refresh();"></vk-data-form>
</vk-data-dialog>
<!-- 添加或编辑的弹窗结束 -->
<!-- 页面内容结束 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="60%">
<self-product-info :order-info="clickInfo" :order-id="clickInfo._id" :goods="clickInfo.goods"
:is-set="isSet"
v-if="dialogVisible && dialogType === 'self-product'" @close="refresh"/>
</el-dialog>
</view>
</template>
<script>
import SelfProductInfo from "./components/selfProductInfo.vue";
import SetSelfSupport from "./components/setSelfSupport.vue";
var that; // 当前页面对象
var vk = uni.vk; // vk实例
var originalForms = {}; // 表单初始化数据
export default {
components: {SetSelfSupport, SelfProductInfo},
data() {
// 页面数据变量
return {
showInfo: false,
dialogTitle: null,
dialogType: null,
dialogVisible: false,
info: null,
clickInfo: null,
title: '',
isSet: false,
infoColumns: [],
// 页面是否请求中或加载中
loading: false,
// init请求返回的数据
data: {},
// 表格相关开始 -----------------------------------------------------------
table1: {
// 表格数据请求地址
action: "admin/order/sys/getList",
// 表格字段显示规则
columns: [
{
key: "orderNo",
title: "订单号",
type: "text",
},
{
key: "amount",
title: "订单金额",
type: "html",
formatter: (val = [], row, column, index) => {
let content = `<div>订单金额:¥` + row.amount + `</div>`
content += `<div>应付金额:¥${row.offAmount}</div>`
if (row.type < 4 && row.payAmount) {
content += `<div>实付金额:¥${row.payAmount ? row.payAmount : ''}</div>`
}
return content
}
},
{
key: "orderStatus",
title: "订单状态",
type: "text",
align: "center",
formatter: (val = [], row, column, index) => {
const orderStatusList = [
'待支付',
'待发货',
'待收货',
'待确认',
'已完成',
'退款审核中',
'退款成功',
'退款失败',
'',
'',
'待报价',
'已派单待完成',
]
let str = orderStatusList[val]
if (val === 7) str += `: ${row.refundRefuseReason}`
return str
}
},
{
key: "user",
title: "买方",
type: "html",
formatter: (val = [], row, column, index) => {
let content = `<div>` + val.mobile + `</div>`
content += `<div>` + val.accountType === 2 ? val.company.companyName : val.person.personName + `</div>`
return content
}
},
{
key: "goods",
title: "商品列表",
type: "html",
},
{
key: "_add_time",
title: "下单时间",
type: "time",
align: "left",
width: 160,
sortable: "custom"
},
{
key: "_add_time_diff",
title: "距离现在",
type: "html",
align: "left",
width: 120,
formatter: (val, row) => vk.pubfn.dateDiff(row._add_time)
},
{
key: "action",
title: "操作",
type: "html",
}
],
// 多选框选中的值
multipleSelection: [],
// 当前高亮的记录
selectItem: ""
},
// 表格相关结束 -----------------------------------------------------------
// 表单相关开始 -----------------------------------------------------------
// 查询表单请求数据
queryForm1: {
// 查询表单数据源,可在此设置默认值
formData: {
type: 1
},
// 查询表单的字段规则 fieldName:指定数据库字段名,不填默认等于key
columns: [
{
key: "type",
title: "类型",
type: "text",
hidden: true
},
{
key: "subType",
title: "服务类型",
type: "select",
data: [
{value: 0, label: '考察服务'},
{value: 1, label: '产品考察服务'},
{value: 2, label: '造价询价服务'},
]
},
{
key: "orderNo",
title: "订单号",
type: "text",
width: 160,
mode: "%%"
},
{
key: "orderStatus",
title: "订单状态",
type: "select",
data: [
{value: 0, label: '待支付'},
{value: 1, label: '待发货'},
{value: 2, label: '待收货'},
{value: 3, label: '待确认'},
{value: 4, label: '已完成'},
{value: 5, label: '退款审核中'},
{value: 6, label: '退款成功'},
{value: 7, label: '退款失败'},
{value: 10, label: '待报价'},
{value: 11, label: '已派单待完成'},
]
},
{
key: "_add_time",
title: "下单时间",
type: "datetimerange",
width: 400,
mode: "[]"
},
]
},
form1: {
// 表单请求数据,此处可以设置默认值
data: {
sort: 0
},
// 表单属性
props: {
// 表单请求地址
action: "",
// 表单字段显示规则
columns: [
{
key: "orderNo",
title: "订单号",
type: "text",
placeholder: "请输入分类名称"
},
{
key: "icon",
title: "图标",
type: "icon",
placeholder: "请选择图标"
},
{
key: "parent_id",
title: "上级分类",
type: "tree-select",
placeholder: "请选择上级分类",
action: "admin/spot/category/sys/getTree",
props: {
list: "rows",
value: "_id",
label: "name",
children: "children"
},
},
{
key: "remark",
title: "备注",
type: "textarea",
maxlength: "99",
showWordLimit: true,
autosize: {
minRows: 2,
maxRows: 10
},
},
{
key: "sort",
title: "排序",
type: "number",
precision: 0,
placeholder: "请输入排序值",
},
],
// 表单验证规则
rules: {
sort: [{
type: 'number',
message: '排序值必须为数字'
}],
name: [
{required: true, message: '分类名称不能为空', trigger: 'blur'},
],
},
// add 代表添加 update 代表修改
formType: "",
// 是否显示表单的弹窗
show: false
}
},
// 其他弹窗表单
formDatas: {},
// 表单相关结束 -----------------------------------------------------------
};
},
// 监听 - 页面每次【加载时】执行(如:前进)
onLoad(options = {}) {
that = this;
vk = that.vk;
that.options = options;
that.options.type = 1
that.init(options);
},
// 监听 - 页面【首次渲染完成时】执行。注意如果渲染速度快,会在页面进入动画完成前触发
onReady() {
},
// 监听 - 页面每次【显示时】执行(如:前进和返回) (页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面)
onShow() {
},
// 监听 - 页面每次【隐藏时】执行(如:返回)
onHide() {
},
// 函数
methods: {
// 页面数据初始化函数
init(options) {
originalForms["form1"] = vk.pubfn.copyObject(that.form1);
},
// 页面跳转
pageTo(path) {
vk.navigateTo(path);
},
// 表单重置
resetForm() {
vk.pubfn.resetForm(originalForms, that);
},
// 搜索
search() {
that.$refs.table1.search();
},
// 刷新
refresh() {
that.$refs.table1.refresh();
this.dialogVisible = false
},
// 获取当前选中的行的数据
getCurrentRow() {
return that.$refs.table1.getCurrentRow();
},
// 监听 - 行的选中高亮事件
currentChange(val) {
that.table1.selectItem = val;
},
// 当选择项发生变化时会触发该事件
selectionChange(list) {
that.table1.multipleSelection = list;
},
// 显示添加页面
addBtn() {
that.resetForm();
that.form1.props.action = 'admin/contract/template/sys/add';
that.form1.props.formType = 'add';
that.form1.props.title = '添加';
that.form1.props.show = true;
},
// 显示修改页面
updateBtn({
item
}) {
that.form1.props.action = 'admin/contract/template/sys/update';
that.form1.props.formType = 'update';
that.form1.props.title = '编辑';
that.form1.props.show = true;
that.form1.data = item;
},
// 删除按钮
deleteBtn({
item,
deleteFn
}) {
deleteFn({
action: "admin/contract/template/sys/delete",
data: {
_id: item._id
},
});
},
// 监听 - 批量操作的按钮点击事件
batchBtn(index) {
switch (index) {
case 1:
vk.toast("批量操作按钮1");
break;
case 2:
vk.toast("批量操作按钮2");
break;
default:
break;
}
},
changeField(id, field, value) {
vk.callFunction({
url: 'admin/old/sys/changeField',
data: {
id, field, value
}
}).then(() => {
this.$refs.table1.refresh()
})
},
doShowInfo(info) {
this.info = info
this.title = '详情'
this.showInfo = true
},
setExpress(item) {
this.clickInfo = item
this.dialogType = 'self-product'
this.dialogTitle = '自营订单派单'
this.isSet = true
this.dialogVisible = true
},
showSelfProductInfo(item) {
this.clickInfo = item
this.dialogType = 'self-product'
this.dialogTitle = '自营订单详情'
this.isSet = false
this.dialogVisible = true
},
setPrice(row) {
this.$prompt('请输入价格', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
}).then(({value}) => {
vk.callFunction({
url: 'admin/order/sys/setPrice',
data: {
_id: row._id,
amount: value
}
}).then(() => {
this.$refs.table1.refresh()
})
})
}
},
// 监听属性
watch: {},
// 过滤器
filters: {},
// 计算属性
computed: {}
};
</script>
<style lang="scss" scoped>
.page-body {
}
</style>
+387
View File
@@ -0,0 +1,387 @@
<template>
<view class="page-body">
<!-- 页面内容开始 -->
<!-- 表格搜索组件开始 -->
<vk-data-table-query v-model="queryForm1.formData" :columns="queryForm1.columns"
@search="search"></vk-data-table-query>
<!-- 表格搜索组件结束 -->
<!-- 自定义按钮区域开始 -->
<view>
<el-row>
</el-row>
</view>
<!-- 自定义按钮区域结束 -->
<!-- 表格组件开始 -->
<vk-data-table ref="table1" :action="table1.action" :columns="table1.columns" :query-form-param="queryForm1"
:pagination="true" @current-change="currentChange"
>
<template v-slot:action="{ row, column, index }">
<!-- <el-button size="mini" @click.native="doShowInfo(row)">详情</el-button>-->
</template>
<template v-slot:isShow="{ row, column, index }">
<el-switch v-if="row.status === 0" v-model="row.isShow" size="mini"
@change="changeField(row._id, 'isShow', $event)"
:active-value="1"
:inactive-value="0"/>
<span v-else></span>
</template>
</vk-data-table>
<!-- 表格组件结束 -->
<!-- 添加或编辑的弹窗开始 -->
<vk-data-dialog v-model="form1.props.show" :title="form1.props.title" width="60%" mode="form"
:close-on-click-modal="false">
<vk-data-form v-model="form1.data" :rules="form1.props.rules" :action="form1.props.action"
:form-type="form1.props.formType" :columns='form1.props.columns' label-width="120px"
@success="form1.props.show = false;refresh();"></vk-data-form>
</vk-data-dialog>
<!-- 添加或编辑的弹窗结束 -->
<!-- 页面内容结束 -->
</view>
</template>
<script>
var that; // 当前页面对象
var vk = uni.vk; // vk实例
var originalForms = {}; // 表单初始化数据
import provinces from "@/uni_modules/vk-uview-ui/libs/address/provinces.json";
import citys from "@/uni_modules/vk-uview-ui/libs/address/citys.json";
import areas from "@/uni_modules/vk-uview-ui/libs/address/areas.json";
export default {
data() {
// 页面数据变量
return {
showInfo: false,
info: null,
title: '',
provinceData: provinces,
cityData: citys,
areaData: areas,
infoColumns: [
{key: "company.companyName", title: "企业名称", type: "text"},
{key: "company.organization", title: "统一社会信用代码", type: "text"},
{key: "company.companyName", title: "公司所在地", type: "text"},
{key: "company.companyName", title: "详细地址", type: "text"},
{key: "company.mailAddress", title: "有效通信地址", type: "text"},
{key: "company.contactEmail", title: "有效邮箱地址", type: "text"},
{key: "company.companyAccount", title: "对公账号", type: "text"},
{key: "company.companyBankName", title: "开户行", type: "text"},
{key: "company.personAccount", title: "个人账号", type: "text"},
{key: "company.personBankName", title: "个人开户行", type: "text"},
{key: "company.accountName", title: "户名", type: "text"},
{key: "company.personBankName", title: "个人开户行", type: "text"},
{key: "company.organizationPath", title: "营业执照", type: "image"},
{key: "company.businessType", title: "经营类目", type: "text"},
{key: "company.invoiceInfo", title: "上开票资料", type: "image"},
{key: "company.taxType", title: "纳税人类型", type: "text"},
{key: "company.taxImage", title: "纳税人资格", type: "image"},
{key: "manager.personName", title: "代理人类型", type: "text"},
{
key: "manager.certType", title: "证件类型", type: "html", formatter: (val, row, column, index) => {
return `<div>${row.certType === 0 ? '身份证' : '护照'}</div>`;
}
},
{key: "manager.idCard", title: "代理人证件号", type: "text"},
{key: "manager.mobile", title: "代理人电话", type: "text"},
{key: "manager.headPhotoPath", title: "身份证头像面", type: "image"},
{key: "manager.backgroundIdCardPath", title: "身份证国徽面", type: "image"},
],
// 页面是否请求中或加载中
loading: false,
// init请求返回的数据
data: {},
// 表格相关开始 -----------------------------------------------------------
table1: {
// 表格数据请求地址
action: "admin/spot/sys/getList",
// 表格字段显示规则
columns: [
{
key: "name",
title: "标题",
type: "text",
align: "left",
},
{
key: "stock",
title: "现货库存",
type: "text",
align: "left",
formatter: (val , row, column, index) => {
return `${val}吨`
}
},
{
key: "address",
title: "收货地",
type: "text",
align: "left",
formatter: (val = [], row, column, index) => {
return val.province.name + "-" + val.city.name + "-" + val.area.name;
}
},
{
key: "",
title: "供货企业",
type: "text",
align: "left",
formatter: (val = [], row, column, index) => {
return row.user.accountType === 1 ? row.user.person.personName : row.user.company.companyName;
}
},
{key: "isShow", title: "是否显示", type: "html"},
{
key: "_add_time",
title: "发布时间",
type: "time",
align: "left",
width: 160,
sortable: "custom"
},
{
key: "_add_time",
title: "距离现在",
type: "dateDiff",
align: "left",
width: 120
},
{key: "action", title: "操作", type: "html"},
],
// 多选框选中的值
multipleSelection: [],
// 当前高亮的记录
selectItem: ""
},
// 表格相关结束 -----------------------------------------------------------
// 表单相关开始 -----------------------------------------------------------
// 查询表单请求数据
queryForm1: {
// 查询表单数据源,可在此设置默认值
formData: {},
// 查询表单的字段规则 fieldName:指定数据库字段名,不填默认等于key
columns: [
// {
// key: "name",
// title: "名称",
// type: "text",
// width: 160,
// mode: "%%"
// },
// {
// key: "remark",
// title: "备注",
// type: "text",
// width: 160,
// mode: "%%"
// },
// {
// key: "_add_time",
// title: "添加时间",
// type: "datetimerange",
// width: 400,
// mode: "[]"
// },
]
},
form1: {
// 表单请求数据,此处可以设置默认值
data: {
sort: 0
},
// 表单属性
props: {
// 表单请求地址
action: "",
// 表单字段显示规则
columns: [{
key: "name",
title: "名称",
type: "text",
placeholder: "请输入分类名称"
},
{
key: "icon",
title: "图标",
type: "icon",
placeholder: "请选择图标"
},
{
key: "parent_id",
title: "上级分类",
type: "tree-select",
placeholder: "请选择上级分类",
action: "admin/spot/category/sys/getTree",
props: {
list: "rows",
value: "_id",
label: "name",
children: "children"
},
},
{
key: "remark",
title: "备注",
type: "textarea",
maxlength: "99",
showWordLimit: true,
autosize: {
minRows: 2,
maxRows: 10
},
},
{
key: "sort",
title: "排序",
type: "number",
precision: 0,
placeholder: "请输入排序值",
},
],
// 表单验证规则
rules: {
sort: [{
type: 'number',
message: '排序值必须为数字'
}],
name: [
{required: true, message: '分类名称不能为空', trigger: 'blur'},
],
},
// add 代表添加 update 代表修改
formType: "",
// 是否显示表单的弹窗
show: false
}
},
// 其他弹窗表单
formDatas: {},
// 表单相关结束 -----------------------------------------------------------
};
},
// 监听 - 页面每次【加载时】执行(如:前进)
onLoad(options = {}) {
that = this;
vk = that.vk;
that.options = options;
that.init(options);
},
// 监听 - 页面【首次渲染完成时】执行。注意如果渲染速度快,会在页面进入动画完成前触发
onReady() {
},
// 监听 - 页面每次【显示时】执行(如:前进和返回) (页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面)
onShow() {
},
// 监听 - 页面每次【隐藏时】执行(如:返回)
onHide() {
},
// 函数
methods: {
// 页面数据初始化函数
init(options) {
originalForms["form1"] = vk.pubfn.copyObject(that.form1);
},
// 页面跳转
pageTo(path) {
vk.navigateTo(path);
},
// 表单重置
resetForm() {
vk.pubfn.resetForm(originalForms, that);
},
// 搜索
search() {
that.$refs.table1.search();
},
// 刷新
refresh() {
that.$refs.table1.refresh();
},
// 获取当前选中的行的数据
getCurrentRow() {
return that.$refs.table1.getCurrentRow();
},
// 监听 - 行的选中高亮事件
currentChange(val) {
that.table1.selectItem = val;
},
// 当选择项发生变化时会触发该事件
selectionChange(list) {
that.table1.multipleSelection = list;
},
// 显示添加页面
addBtn() {
that.resetForm();
that.form1.props.action = 'admin/contract/template/sys/add';
that.form1.props.formType = 'add';
that.form1.props.title = '添加';
that.form1.props.show = true;
},
// 显示修改页面
updateBtn({
item
}) {
that.form1.props.action = 'admin/contract/template/sys/update';
that.form1.props.formType = 'update';
that.form1.props.title = '编辑';
that.form1.props.show = true;
that.form1.data = item;
},
// 删除按钮
deleteBtn({
item,
deleteFn
}) {
deleteFn({
action: "admin/contract/template/sys/delete",
data: {
_id: item._id
},
});
},
// 监听 - 批量操作的按钮点击事件
batchBtn(index) {
switch (index) {
case 1:
vk.toast("批量操作按钮1");
break;
case 2:
vk.toast("批量操作按钮2");
break;
default:
break;
}
},
changeField(id, field, value) {
vk.callFunction({
url: 'admin/spot/sys/changeField',
data: {
id, field, value
}
}).then(() => {
this.$refs.table1.refresh()
})
},
doShowInfo(info) {
this.info = info
this.title = '详情'
this.showInfo = true
},
},
// 监听属性
watch: {},
// 过滤器
filters: {},
// 计算属性
computed: {}
};
</script>
<style lang="scss" scoped>
.page-body {
}
</style>