货无忧安装平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

608 lines
13 KiB

<template>
<BasicContainer ref='basicContainer' :option="option">
<!-- 头部 -->
<template #head>
</template>
<!-- 主体 -->
<template #body>
<view class="main">
<scroll-view class="scvmabx" :style="{height: details.scrollheight}" @scrolltolower="()=>{}" scroll-y="true"
@touchmove.stop>
<view class="main_container">
<!-- -- 售后类型 -->
<view class="info_item border_bottom">
<view class="info_item_title flex-c-sb">
<view class="">
</view>
<!-- 新增售后包件 -->
<view class="flex addBtn" @click="handleAddPackage">
<view class="addButton">
<u-icon name="close-circle" color="#2F8DFF" size="36"></u-icon>
</view>
<text class="ml10 fwn">
添加
</text>
</view>
</view>
</view>
<!-- 售后包件列表 -->
<view :class="{packageList: true, pd20: details.packageList.length > 0}"
:style="{height: (details.packageList.length > 0 ?(40 * details.packageList.length) + ((details.packageList.length - 1) * 10): 0) + 'px'}">
<block v-for="(item, index) in details.packageList">
<view :class="{'packageItem': true, 'flex-c-sb': true, 'mt20': index !== 0}">
<view class="inputBox flex1 flex">
<input class="packageInput flex1" v-model="item.code" placeholder="请输入包条码" />
<view class="scanIcon flex-c-c" @click.stop="()=> handleScan(item)">
<u-icon name="scan" color="#2F8DFF" size="60"></u-icon>
</view>
</view>
<view class="ml20 flex-c-c" @click="()=> handleRemovePackage(index)">
<u-icon name="trash" color="#8792AA" size="36"></u-icon>
<text class="ml10 info">
删除
</text>
</view>
</view>
</block>
</view>
<!-- 行 -- 售后类型 -->
<view class="info_item border_bottom">
<view class="info_item_title flex-c-sb" @click="details.popUpObj.afterSalesType = true">
<view class="">
售 后 类 型
</view>
<view class="flex" @click="handleShowMyDrawer">
<text class="mr10 fwn info">
{{ details.form.typeName || '待确定'}}
</text>
<u-icon name="arrow-right" color="#AFB4BA" size="36"></u-icon>
</view>
</view>
</view>
<!-- 行 -- 图片 -->
<view class="info_item border_bottom">
<view class="info_item_title">
图 片
</view>
<view class="imgList flex mt20">
<!-- 单个图片 -->
<block v-for="(item, index) in details.imgList" :key="item">
<view class="image_conatiner mr20">
<image :src="item.url" mode=""></image>
<!-- 删除 -->
<view class="removeIcon" @click="()=> handleRmove(index)">
<u-icon name="close-circle-fill" color="#666" size="50"></u-icon>
</view>
</view>
</block>
<!-- 添加图片 -->
<view class="image_conatiner addImg flex-c-c" @click="handleUploadFile">
<u-icon name="photo-fill" color="#999" size="100"></u-icon>
</view>
</view>
</view>
<!-- 行 -- 备注 -->
<view class="info_item ">
<view class="info_item_title">
备 注
</view>
<view class="mt20">
<u--textarea v-model="details.form.remark" placeholder="请输入备注"></u--textarea>
</view>
</view>
</view>
</scroll-view>
<view class="footer" @click="handleSubmit">
<view class="button subColor">
确 认
</view>
</view>
</view>
</template>
</BasicContainer>
<MyDrawer ref="myDrawer">
<template #content>
<picker-view v-if="details.visible" :indicator-style="details.indicatorStyle" :immediate-change="true"
:value="details.value" @change="bindChange" class="picker-view">
<picker-view-column>
<view class="item" v-for="(item, index) in details.pickerArr" :key="index">
{{ item.label }}
</view>
</picker-view-column>
</picker-view>
</template>
</MyDrawer>
<tips ref="tip" />
<!-- #ifdef APP -->
<saomiao2 :ishidestop="scanState !== 0"></saomiao2>
<!-- #endif -->
</template>
<script lang="ts" setup>
import {
postInstallAfterSales,
} from '@/api/user.js'
import {
onLoad,
onShow,
onHide,
} from '@dcloudio/uni-app'
import { nextTick, reactive, ref, toRefs } from "vue";
import utils from '@/utils/utils.js'
import useSystemSettingsStore from '@/store/useSystemSettingsStore';
import { storeToRefs } from 'pinia';
const { scanState } = storeToRefs(useSystemSettingsStore())
// 组件配置
const option = reactive({
// 标题
title: '发起售后',
// 下拉刷新回调函数
async pullDownRefreshInitPage() {
return null
},
// 触底加载回到函数
reachBottomInitPage: async () => { return null },
haveData: true,
isEnd: false,
pageType: 'add' as 'add' | 'edit',
pageLoading: false
})
// 组件实例
const basicContainer = ref()
const myDrawer = ref()
const tip = ref()
let details = reactive({
/** 主页面高度 */
scrollheight: '80vh',
/** 表单数据 */
form: {
type: '',
typeName: '',
/** 备注 */
remark: ''
},
/** 售后包件列表 */
packageList: [{ code: '' }],
/** 售后图片列表 */
imgList: [],
/** 扫描码值 */
scancode: '',
/** 异常类型数组 */
afterSalesTypeOptions: [
[{
label: '雪月夜',
// 其他属性值
id: 2021
// ...
}, {
label: '冷夜雨',
id: 804
}]
],
scanStateChooseIndex: 0,
/** 是否显示弹窗 */
popUpObj: {
/** 异常类型 */
afterSalesType: false
},
/** picker行高度 */
indicatorStyle: `height: 40px;`,
visible: false,
value: [0],
pickerArr: [
{
label: '调试',
value: '1'
},
{
label: '维修',
value: '2'
},
{
label: '理赔',
value: '3'
},
{
label: '待确认',
value: '4'
}, {
label: '换货',
value: '5'
},
{
label: '工厂补单',
value: '6'
},
],
/** 页面信息 */
pageInfo: {
id: ''
}
})
onLoad((e) => {
details.pageInfo.id = e.id
})
onShow(async () => {
// #ifdef APP
// 初始化关闭监听
uni.$off('scancodedate')
// init()
uni.$on('scancodedate', function (code) {
console.log('code :>> ', code);
if (code) {
console.log(code);
details.scancode = code
scandata()
}
})
// #endif
await nextTick()
// basicContainer.value.startPullDownRefresh()
const _height = await utils.getViewDistanceFormTop('.scvmabx')
details.scrollheight = Number(_height.replace('px', '')) - 100 + 'px'
})
const scandata = () => { }
const initpage = () => { }
/** 关闭弹窗 */
const hidePopUp = (node) => {
details.visible = false
node.value.details.showPopUp = false
}
/** 显示售后类型选择弹窗 */
const handleShowMyDrawer = () => {
details.visible = true
myDrawer.value.setDetails({
showPopUp: true,
height: '50vh',
success() {
console.log('details.value :>> ', details.value);
try {
const _item = details.pickerArr[details.value[0]]
details.form.type = _item.value
details.form.typeName = _item.label
} catch (err) {
console.log('err :>> ', err);
} finally {
hidePopUp(myDrawer)
}
},
close() {
hidePopUp(myDrawer)
}
})
}
/** 显示扫描 */
const handleScan = (value) => {
console.log('value :>> ', value);
// #ifdef MP-WEIXIN
// 微信小程序适配
uni.scanCode({
success(res) {
console.log('res :>> ', res);
console.log('res.result :>> ', res.result);
for (let i = 0; i < details.packageList.length; i++) {
const value = details.packageList[i]
if (value.code === res.result) return utils.handleToast('码值已存在')
}
value.code = res.result
// scandata()
}
})
return
// #endif
uni.navigateTo({
url: '/pagesHome/pages/Video/Video'
})
}
/** 新增售后包件 */
const handleAddPackage = () => {
details.packageList.push({ code: '' })
}
/** 删除售后包件 */
const handleRemovePackage = (index : number) => {
details.packageList.splice(index, 1)
}
/** picker切换时执行 */
const bindChange = function (e, type) {
console.log('type :>> ', type);
console.log('e :>> ', e);
details.value = e.detail.value
}
/** 新增图片 */
const handleUploadFile = () => {
const successByUpload = (res) => {
console.log('res :>> ', res);
const { data } = res
const _data = JSON.parse(data)
console.log('_data :>> ', _data);
const { code, data: img } = _data
details.imgList.push({ url: img, name: img })
}
utils.handleUploadFile({
successByUpload
})
}
/** 移除图片 */
const handleRmove = (index) => {
tip.value.setdetails({
isshow: true,
content: '确认移除',
cancelTxt: '取消',
confirmTxt: '确认',
success() {
details.imgList.splice(index, 1)
// 关闭弹窗
tip.value.setdetails({ isshow: false })
},
cancel() {
// 关闭弹窗
tip.value.setdetails({ isshow: false })
}
})
}
/** 提交 */
const handleSubmit = () => {
if (!details.form.type) return utils.handleToast('请选择售后类型')
tip.value.setdetails({
isshow: true,
content: '确认提交',
cancelTxt: '取消',
confirmTxt: '确认',
async success() {
try {
option.pageLoading = true
const submitData = { type: details.form.type, install_id: details.pageInfo.id, remark: details.form.remark, images: details.imgList, packages: [] }
for (let i = 0; i < details.packageList.length; i++) {
const _item = details.packageList[i]
_item.code && submitData.packages.push(_item.code)
}
const res = await postInstallAfterSales(submitData)
const { code, data } = res
if (code !== 200) return
uni.navigateBack()
} catch (err) {
console.log('err :>> ', err);
//TODO handle the exception
} finally {
option.pageLoading = false
}
// 关闭弹窗
tip.value.setdetails({ isshow: false })
},
cancel() {
// 关闭弹窗
tip.value.setdetails({ isshow: false })
}
})
}
</script>
<style lang="scss" scoped>
@import url("@/utils/style/common.scss");
// 主体内容
.main {
font-family: 黑体;
position: relative;
border-top-right-radius: 20upx;
border-top-left-radius: 20upx;
background-color: #fff;
.scvmabx {
background-color: #fff;
}
.info {
color: #AFB4BA;
}
.main_container {
// padding: 0 20upx;
}
// 行
.info_item {
margin: 0 20upx;
padding: 20upx;
.info_item_title {
// padding: 0 0 20upx;
font-weight: bold;
height: 40upx;
line-height: 40upx;
}
&.border_bottom {
border-bottom: 2upx solid #eee;
}
:deep(.u-textarea) {
background-color: #f5f5f6;
border: none;
height: 200upx;
}
// 添加
.addBtn {
color: #2F8DFF;
.addButton {
transform: rotate(45deg);
}
}
}
// 包件列表
.packageList {
background: #f5f5f6;
transition: all 0.3s;
overflow: hidden;
.packageItem {
$inputHeight: 80upx;
.inputBox {
position: relative;
border-radius: calc($inputHeight / 2);
overflow: hidden;
background: #fff;
.packageInput {
height: $inputHeight;
padding: 0 40upx;
}
.scanIcon {
padding: 0 20upx;
// position: absolute;
// right: 40upx;
// top: 50%;
// transform: translateY(-50%);
}
}
}
}
// 图片列表
.imgList {
flex-wrap: wrap;
.image_conatiner {
position: relative;
.removeIcon {
position: absolute;
top: 0;
right: 0;
transform: translate(40%, -40%);
opacity: 0.9;
}
}
.addImg {
width: 160upx;
height: 160upx;
border-radius: 20upx;
box-sizing: border-box;
border: 2upx solid #eee;
}
image {
width: 160upx;
height: 160upx;
border-radius: 20upx;
}
}
}
// 底部
.footer {
box-sizing: border-box;
height: 100px;
padding-top: 30upx;
display: flex;
justify-content: space-between;
.button {
height: 80upx;
display: flex;
align-items: center;
justify-content: center;
flex: 1;
// margin: 10upx;
border: 2upx solid #b5babf;
border-radius: 80upx;
margin: 0 10upx;
padding: 0 10upx;
font-size: 0.9rem;
font-weight: bold;
&.subColor {
// border-color: var(--subjectColor);
// color: var(--subjectColor);
background-color: var(--subjectColor);
color: #fff;
border: none;
}
&.primaryColor {
// border-color: var(--primaryColor);
// color: var(--primaryColor);
background-color: var(--primaryColor);
color: #fff;
border: none;
}
&.errColor {
// border-color: var(--errColor);
// color: var(--errColor);
background-color: var(--errColor);
color: #fff;
border: none;
}
}
}
</style>