Compare commits
10 Commits
59485ce24c
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32c78e0a82 | ||
|
|
a1835abdc8 | ||
|
|
239039f712 | ||
|
|
04356796fa | ||
|
|
5aa7498225 | ||
|
|
d4d37ee13b | ||
|
|
954c1baa96 | ||
|
|
4355121fff | ||
|
|
340c5cf6ef | ||
|
|
0715c338f4 |
@@ -173,3 +173,56 @@ export function crmMarketInformationApprovalUnSuccess(data) {
|
|||||||
isTransformResponse:false
|
isTransformResponse:false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//任务清单
|
||||||
|
export function SalesManTaskList(data) {
|
||||||
|
return request.get({
|
||||||
|
url: '/crm/app/schedulerTask/SalesManTaskList',
|
||||||
|
data
|
||||||
|
},{
|
||||||
|
isTransformResponse:false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//主线任务列表
|
||||||
|
export function SalesManTaskDetailList(data) {
|
||||||
|
return request.get({
|
||||||
|
url: '/crm/app/schedulerTask/SalesManTaskDetailList',
|
||||||
|
data
|
||||||
|
},{
|
||||||
|
isTransformResponse:false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//任务计划新增
|
||||||
|
export function taskPlanAdd(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/crm/app/schedulerTask/add',
|
||||||
|
data
|
||||||
|
},{
|
||||||
|
isTransformResponse:false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//任务计划查看
|
||||||
|
export function TaskPlanList(data) {
|
||||||
|
return request.get({
|
||||||
|
url: '/crm/app/schedulerTask/TaskPlanList',
|
||||||
|
data
|
||||||
|
},{
|
||||||
|
isTransformResponse:false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//我的审批
|
||||||
|
export function getMyReviewList(data) {
|
||||||
|
return request.get({
|
||||||
|
url: "/crm/app/schedulerTask/myReview",
|
||||||
|
data
|
||||||
|
},{
|
||||||
|
isTransformResponse:false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -125,4 +125,57 @@ export function querytodaytasknum(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**主动上报 begin */
|
||||||
|
// 详情
|
||||||
|
export function patrolBugDetail(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/patrol/patrolBug/detail',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询异常上报表列表
|
||||||
|
export function patrolBugList(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/patrol/patrolBug/list',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加问题上报
|
||||||
|
export function patrolBugAdd(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/patrol/patrolBug/addBug',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 编辑问题
|
||||||
|
export function patrolBugEdit(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/patrol/patrolBug/editBug',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 删除问题
|
||||||
|
export function patrolBugDel(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/patrol/patrolBug/delBug',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 添加追踪记录
|
||||||
|
export function patrolBugAddLog(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/patrol/patrolBug/addBuglog',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/**主动上报 end */
|
||||||
|
|
||||||
|
// 验证NFC扫描是否正确
|
||||||
|
export function patroltaskValidateNfc(data) {
|
||||||
|
return request.post({
|
||||||
|
url: '/patrol/patroltask/validateNfc',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<view class="nfc-title">
|
<view class="nfc-title">
|
||||||
<uni-icons type="closeempty" size="20" class="nfc-close" @click="handleClose"></uni-icons>NFC识别
|
<uni-icons type="closeempty" size="20" class="nfc-close" @click="handleClose"></uni-icons>NFC识别
|
||||||
</view>
|
</view>
|
||||||
<block v-if="formData.deviceId==''">
|
<block v-if="!deviceId">
|
||||||
<view class="nfc-pic">
|
<view class="nfc-pic">
|
||||||
<img class="nfc-pic-animal" :src="'static/images/polling/nfc-logo.png'" />
|
<img class="nfc-pic-animal" :src="'static/images/polling/nfc-logo.png'" />
|
||||||
</view>
|
</view>
|
||||||
@@ -40,16 +40,20 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onBeforeUnmount,onMounted } from "vue";
|
import { ref, onBeforeUnmount,onMounted,getCurrentInstance } from "vue";
|
||||||
import { parseTime } from '@/utils/datetime.js';
|
import { parseTime } from '@/utils/datetime.js';
|
||||||
|
import { patroltaskValidateNfc } from '@/api/polling.js'
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
const props = defineProps({
|
||||||
|
nfcId:{},
|
||||||
|
})
|
||||||
|
|
||||||
// 定义组件 emits
|
// 定义组件 emits
|
||||||
const emit = defineEmits(['close',"changeNfc"]);
|
const emit = defineEmits(['close',"changeNfc"]);
|
||||||
|
|
||||||
// 状态管理
|
// 状态管理
|
||||||
const formData = ref({
|
const deviceId = ref(undefined);
|
||||||
deviceId: "", //录入的id
|
|
||||||
});
|
|
||||||
const readStatus=ref(false);//读取状态 true 成功
|
const readStatus=ref(false);//读取状态 true 成功
|
||||||
|
|
||||||
// 变量初始化
|
// 变量初始化
|
||||||
@@ -81,7 +85,8 @@ function open() {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
deviceId.value=undefined;
|
||||||
|
readStatus.value=false;
|
||||||
initNFC();
|
initNFC();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("打开NFC失败:", e);
|
console.error("打开NFC失败:", e);
|
||||||
@@ -177,7 +182,7 @@ function handleNewIntent() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 读取NFC数据
|
// 读取NFC数据
|
||||||
function readNFCData() {
|
async function readNFCData() {
|
||||||
try {
|
try {
|
||||||
const main = plus.android.runtimeMainActivity();
|
const main = plus.android.runtimeMainActivity();
|
||||||
const _intent = main.getIntent();
|
const _intent = main.getIntent();
|
||||||
@@ -193,9 +198,23 @@ function readNFCData() {
|
|||||||
function bytesToString(result) {
|
function bytesToString(result) {
|
||||||
return String.fromCharCode(...result);
|
return String.fromCharCode(...result);
|
||||||
}
|
}
|
||||||
formData.value.deviceId = bytesToString(result).substring(3);
|
let nfcContent = bytesToString(result).substring(3);
|
||||||
emit("changeNfc", formData.value.deviceId);
|
console.log("nfcContent=>",nfcContent)
|
||||||
readStatus.value=true;
|
deviceId.value=nfcContent;
|
||||||
|
|
||||||
|
// 调用后台接口验证NFC内容的正确性
|
||||||
|
let param = {
|
||||||
|
nfcId:props.nfcId,
|
||||||
|
nfcContent
|
||||||
|
}
|
||||||
|
// console.log("param=>",param)
|
||||||
|
let res = await patroltaskValidateNfc(param);
|
||||||
|
// console.log("patroltaskValidateNfc=>",res)
|
||||||
|
if(!res){
|
||||||
|
emit("changeNfc", nfcContent);
|
||||||
|
readStatus.value=true;
|
||||||
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("读取NDEF数据错误:", e);
|
console.log("读取NDEF数据错误:", e);
|
||||||
uni.showToast({ title: "读取数据失败,请重新读取", icon: "none" });
|
uni.showToast({ title: "读取数据失败,请重新读取", icon: "none" });
|
||||||
|
|||||||
@@ -5,15 +5,15 @@
|
|||||||
<view class="picker-item" @click="takePhoto">
|
<view class="picker-item" @click="takePhoto">
|
||||||
<text>拍照</text>
|
<text>拍照</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="picker-item" @click="choosePhoto">
|
<!-- <view class="picker-item" @click="choosePhoto">
|
||||||
<text>选择照片</text>
|
<text>选择照片</text>
|
||||||
</view>
|
</view> -->
|
||||||
<view class="picker-item" @click="takeVideo">
|
<view class="picker-item" @click="takeVideo">
|
||||||
<text>拍摄视频</text>
|
<text>拍摄视频</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="picker-item" @click="chooseVideoFromAlbum">
|
<!-- <view class="picker-item" @click="chooseVideoFromAlbum">
|
||||||
<text>选择视频</text>
|
<text>选择视频</text>
|
||||||
</view>
|
</view> -->
|
||||||
<view class="picker-item" @click="closePicker">
|
<view class="picker-item" @click="closePicker">
|
||||||
<text>取消</text>
|
<text>取消</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -39,17 +39,17 @@ const takePhoto = () => {
|
|||||||
captureMedia("image", "camera");
|
captureMedia("image", "camera");
|
||||||
}
|
}
|
||||||
|
|
||||||
const choosePhoto = () => {
|
// const choosePhoto = () => {
|
||||||
captureMedia("image", "album");
|
// captureMedia("image", "album");
|
||||||
}
|
// }
|
||||||
|
|
||||||
const takeVideo = () => {
|
const takeVideo = () => {
|
||||||
captureMedia("video", "camera");
|
captureMedia("video", "camera");
|
||||||
}
|
}
|
||||||
|
|
||||||
const chooseVideoFromAlbum = () => {
|
// const chooseVideoFromAlbum = () => {
|
||||||
captureMedia("video", "album");
|
// captureMedia("video", "album");
|
||||||
}
|
// }
|
||||||
|
|
||||||
const captureMedia = async (type, source) => {
|
const captureMedia = async (type, source) => {
|
||||||
showPicker.value = false;
|
showPicker.value = false;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ const props = defineProps({
|
|||||||
searchKeywords:{//搜索文本
|
searchKeywords:{//搜索文本
|
||||||
type:String
|
type:String
|
||||||
},
|
},
|
||||||
searchType:{//哪种类型显示对象 typeId:1-首页,2-业务首页,3-消息 之后可以自动添加
|
searchType:{//哪种类型显示对象 typeId:1-首页,2-业务首页,3-消息, 4-问题,5-上报问题 之后可以自动添加
|
||||||
type:Object
|
type:Object
|
||||||
},
|
},
|
||||||
searchTypeList:{//类型列表
|
searchTypeList:{//类型列表
|
||||||
|
|||||||
@@ -18,4 +18,9 @@ export const RequestCodeEnum = {
|
|||||||
export const RequestErrMsgEnum = {
|
export const RequestErrMsgEnum = {
|
||||||
ABORT: 'request:fail abort',
|
ABORT: 'request:fail abort',
|
||||||
TIMEOUT: 'request:fail timeout'
|
TIMEOUT: 'request:fail timeout'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 特殊接口不弹默认窗口处理
|
||||||
|
export const RequestUrlAlertEum=[
|
||||||
|
'/patrol/patroltask/validateNfc'
|
||||||
|
]
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"name" : "718友晟",
|
"name" : "718友晟",
|
||||||
"appid" : "__UNI__0B682E1",
|
"appid" : "__UNI__0B682E1",
|
||||||
"description" : "",
|
"description" : "",
|
||||||
"versionName" : "1.0.2",
|
"versionName" : "1.0.0",
|
||||||
"versionCode" : "100",
|
"versionCode" : "100",
|
||||||
"transformPx" : false,
|
"transformPx" : false,
|
||||||
/* 5+App特有相关 */
|
/* 5+App特有相关 */
|
||||||
@@ -64,6 +64,7 @@
|
|||||||
"<uses-permission android:name=\"android.permission.NFC\"/>",
|
"<uses-permission android:name=\"android.permission.NFC\"/>",
|
||||||
"<uses-feature android:name=\"android.hardware.nfc\" android:required=\"true\"/>",
|
"<uses-feature android:name=\"android.hardware.nfc\" android:required=\"true\"/>",
|
||||||
"<uses-permission android:name=\"android.permission.POST_NOTIFICATIONS\"/>"
|
"<uses-permission android:name=\"android.permission.POST_NOTIFICATIONS\"/>"
|
||||||
|
|
||||||
],
|
],
|
||||||
"abiFilters" : [ "armeabi-v7a", "arm64-v8a" ],
|
"abiFilters" : [ "armeabi-v7a", "arm64-v8a" ],
|
||||||
"minSdkVersion" : 23,
|
"minSdkVersion" : 23,
|
||||||
|
|||||||
@@ -663,6 +663,30 @@
|
|||||||
"navigationBarTitleText": ""
|
"navigationBarTitleText": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/polling/problemInitiativeList",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/polling/problemInitiative",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/polling/problemInitiativeDetail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/polling/problemInitiativeLog",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/business/polling/nfcTest/index",
|
"path": "pages/business/polling/nfcTest/index",
|
||||||
"style": {
|
"style": {
|
||||||
@@ -752,6 +776,27 @@
|
|||||||
{
|
{
|
||||||
"path": "pages/business/CRM/scheduler/taskListViewing",
|
"path": "pages/business/CRM/scheduler/taskListViewing",
|
||||||
|
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/CRM/scheduler/taskViewingDetail",
|
||||||
|
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/CRM/scheduler/taskPlanList",
|
||||||
|
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/business/CRM/scheduler/taskPlanReview",
|
||||||
|
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": ""
|
"navigationBarTitleText": ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,19 +19,9 @@
|
|||||||
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</navigator>
|
|
||||||
<view class="item-border"></view>
|
|
||||||
<navigator url="/pages/business/CRM/scheduler/taskPlanAdded">
|
|
||||||
<view class="list-item item-padding">
|
|
||||||
<img class="l-icon" :src="'static/images/business/icon-khryss.png'"/>
|
|
||||||
<text>任务计划新增</text>
|
|
||||||
<view class="list-right">
|
|
||||||
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</navigator>
|
</navigator>
|
||||||
<view class="item-border"></view>
|
<view class="item-border"></view>
|
||||||
<navigator url="/pages/business/CRM/plan/planView">
|
<navigator url="/pages/business/CRM/scheduler/taskPlanList">
|
||||||
<view class="list-item item-padding">
|
<view class="list-item item-padding">
|
||||||
<img class="l-icon" :src="'static/images/business/icon-jhck.png'"/>
|
<img class="l-icon" :src="'static/images/business/icon-jhck.png'"/>
|
||||||
<text>任务计划查看</text>
|
<text>任务计划查看</text>
|
||||||
@@ -40,6 +30,16 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</navigator>
|
</navigator>
|
||||||
|
<view class="item-border"></view>
|
||||||
|
<navigator url="/pages/business/CRM/scheduler/taskPlanReview">
|
||||||
|
<view class="list-item item-padding">
|
||||||
|
<img class="l-icon" :src="'static/images/business/icon-khryss.png'"/>
|
||||||
|
<text>任务计划审批</text>
|
||||||
|
<view class="list-right">
|
||||||
|
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</navigator>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -1,219 +1,412 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="con-body">
|
<view class="con-body">
|
||||||
<view class="con-bg">
|
<view class="con-bg">
|
||||||
<!-- 头部 -->
|
<!-- 头部 -->
|
||||||
<customHeader ref="customHeaderRef" :title="'任务清单查看'" :leftFlag="true" :rightFlag="true">
|
<customHeader ref="customHeaderRef" :title="!searchShow ? '任务清单查看' : '搜索'"
|
||||||
<template #right>
|
:leftFlag="true" :rightFlag="true" @back="handleBack"
|
||||||
<view class="head-right">
|
:searchType="searchShow ? 1 : undefined">
|
||||||
|
<!-- <template #right v-if="!searchShow">
|
||||||
</view>
|
<view class="head-right" @click="handleRead">
|
||||||
</template>
|
<img :src="'static/images/icon-clean@2x.png'" />清除未读
|
||||||
</customHeader>
|
</view>
|
||||||
|
</template> -->
|
||||||
|
</customHeader>
|
||||||
|
|
||||||
<!-- 高度来避免头部遮挡 -->
|
<!-- 高度来避免头部遮挡 -->
|
||||||
<view class="top-height" :style="{ paddingTop: navBarPaddingTop + 'px' }"></view>
|
<view class="top-height"></view>
|
||||||
|
|
||||||
<!-- 正文内容 -->
|
<!-- 搜索处理 -->
|
||||||
<view class="all-body">
|
<customSearch v-if="searchShow" :searchKeywords="searchText" :searchType="searchTypeObj"
|
||||||
<!-- 搜索 @blur="blur" @focus="focus" @input="input" @cancel="cancel" @clear="clear"-->
|
:checkTypeObj="notictTypeCheck" @confirm="handleSearchConfirm">
|
||||||
<!-- <view class="search">
|
</customSearch>
|
||||||
<uni-search-bar class="custom-search" radius="28" placeholder="请输入客户名称" clearButton="auto"
|
<view class="search" v-else @click="handleSearchFocus">
|
||||||
cancelButton="none" bgColor="#6FA2F8" textColor="#ffffff"
|
<view class="search-bg">
|
||||||
v-model="searchValue"
|
<view class="search-left">
|
||||||
/>
|
{{ notictTypeCheck.name ? notictTypeCheck.name : '全部' }}
|
||||||
<button type="default" @click="handleSearch" size="mini" class="btn-search">查询</button>
|
</view>
|
||||||
</view> -->
|
<view class="search-right">
|
||||||
|
<input class="uni-input" v-model="inputval" placeholder="请输入您想查询的内容"
|
||||||
|
placeholder-class="search-color" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 分页部分 -->
|
<!-- 正文内容 -->
|
||||||
<mescroll-uni ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
|
<!-- 分页部分 -->
|
||||||
:up="upOption" :down="downOption" :fixed="false" textColor="#ffffff" bgColor="#ffffff"
|
<mescroll-uni v-if="!searchShow" ref="mescrollRef" @init="mescrollInit"
|
||||||
class="scroll-h" :class="{'loading-scroll':cssFlag}"
|
@down="downCallback" @up="upCallback" :up="upOption" :down="downOption"
|
||||||
>
|
:fixed="false" textColor="#ffffff" bgColor="#ffffff" class="scroll-h"
|
||||||
<view class="white-bg margin-bottom20" v-for="(item, index) in list" :key="index" @click="handleDetail(item)">
|
:class="{ 'loading-scroll': cssFlag }">
|
||||||
<view class="report-list">
|
<view class="white-bg margin-bottom20" v-for="(item, index) in list" :key="index"
|
||||||
<view class="title">{{ item.title }}</view>
|
@click="showDetail(item)">
|
||||||
<view class="r-list">
|
<view>
|
||||||
<view class="r-name">{{ item.name }}</view>
|
<view class="report-list">
|
||||||
<view class="r-right btn-orange" size="mini">{{ item.statusName }}</view>
|
<view class="title" style="font-size: 30rpx">
|
||||||
</view>
|
任务名称:{{ item.taskName }}
|
||||||
<view class="border-bottom"></view>
|
</view>
|
||||||
<view class="r-list">
|
<view class="r-left"
|
||||||
<view class="r-left">报告类型</view>
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
<view class="r-right">{{ item.reportTypeName }}</view>
|
主线任务类型:{{ item.mainTaskName }}
|
||||||
</view>
|
</view>
|
||||||
<view class="border-bottom"></view>
|
<view class="r-left"
|
||||||
<view class="r-list">
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
<view class="r-left">报告人</view>
|
计划开始时间:{{ formatDateStr(item.mainTaskStartTime) }}
|
||||||
<view class="r-right">{{ item.reportPeople }}</view>
|
</view>
|
||||||
</view>
|
<view class="r-left"
|
||||||
<view class="border-bottom"></view>
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
<view class="r-list">
|
计划结束时间:{{ formatDateStr(item.mainTaskEndTime) }}
|
||||||
<view class="r-left">报告日期</view>
|
</view>
|
||||||
<view class="r-right">{{ item.dateStr }}</view>
|
<view class="r-left"
|
||||||
</view>
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
</view>
|
是否超期:{{ item.mainTaskIsOverdue }}
|
||||||
</view>
|
</view>
|
||||||
</mescroll-uni>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</mescroll-uni>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import {
|
||||||
import customHeader from '@/components/customHeader.vue'
|
ref,
|
||||||
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
onMounted,
|
||||||
import { getNavBarPaddingTop } from '@/utils/system.js'
|
watch
|
||||||
import { SalesManTaskList } from '@/api/crm/api_ys.js'
|
} from 'vue'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import customSearch from '@/components/customSearch.vue'
|
||||||
|
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||||
|
import {
|
||||||
|
getNavBarPaddingTop
|
||||||
|
} from '@/utils/system.js'
|
||||||
|
|
||||||
// 获取导航栏高度用于内容区域padding
|
import {
|
||||||
const navBarPaddingTop = ref(0);
|
SalesManTaskList
|
||||||
onMounted(() => {
|
} from '@/api/crm/api_ys.js'
|
||||||
navBarPaddingTop.value = getNavBarPaddingTop() * 2;
|
import {
|
||||||
})
|
getDate
|
||||||
|
} from '@/utils/datetime.js'
|
||||||
|
|
||||||
let searchValue = ref(null)
|
|
||||||
// 查询搜索跳转
|
|
||||||
let handleSearch = () => {
|
|
||||||
console.log(searchValue.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增
|
import {
|
||||||
let handleAdd = ()=>{
|
onLoad,
|
||||||
uni.navigateTo({ url:'/pages/business/CRM/visitorReportAdd' })
|
onShow,
|
||||||
}
|
onUnload,
|
||||||
|
onHide
|
||||||
|
} from '@dcloudio/uni-app'
|
||||||
|
// 获取导航栏高度用于内容区域padding
|
||||||
|
const navBarPaddingTop = ref(0);
|
||||||
|
onMounted(() => {
|
||||||
|
navBarPaddingTop.value = getNavBarPaddingTop() * 2;
|
||||||
|
uni.$on('updateStatus', markVisited)
|
||||||
|
})
|
||||||
|
// 搜索处理
|
||||||
|
let searchShow = ref(false);
|
||||||
|
let searchText = ref(undefined);
|
||||||
|
let searchTypeObj = ref({
|
||||||
|
typeId: 3,
|
||||||
|
typeName: '消息类型'
|
||||||
|
});
|
||||||
|
|
||||||
// 查询列表
|
let notictTypeCheck = ref({}); //选中类型
|
||||||
let list = ref([]);
|
|
||||||
const mescrollRef = ref(null);
|
|
||||||
const upOption = ref({
|
|
||||||
page: { num: 0, size: 10 },
|
|
||||||
noMoreSize: 5,
|
|
||||||
empty: {
|
|
||||||
tip: '~ 空空如也 ~',
|
|
||||||
icon: "../../static/images/mescroll-empty.png"
|
|
||||||
},
|
|
||||||
textLoading: '加载中...',
|
|
||||||
textNoMore: '已经到底了'
|
|
||||||
});
|
|
||||||
|
|
||||||
const downOption = ref({
|
// 查询列表
|
||||||
auto: true,
|
let list = ref([]);
|
||||||
textInOffset: '下拉刷新',
|
// 新增状态变量存储搜索条件
|
||||||
textOutOffset: '释放更新',
|
const inputval = ref(''); // 搜索内容
|
||||||
textLoading: '刷新中...'
|
let searchValue = ref(null)
|
||||||
});
|
//监视查询的内容的变化
|
||||||
|
watch(searchValue, (newValue, oldValue) => {
|
||||||
|
//变化了之后,重新查询内容
|
||||||
|
var data = {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
};
|
||||||
|
SalesManTaskList(data).then(res => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
//设置列表数据
|
||||||
|
list.value = res.rows;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
onHide(() => {
|
||||||
|
searchShow.value = false;
|
||||||
|
})
|
||||||
|
|
||||||
let cssFlag=ref(false);//控制样式
|
// 搜索返回操作
|
||||||
const mescrollInit = (mescroll) => {
|
const handleBack = () => {
|
||||||
cssFlag.value = true;
|
searchShow.value = false;
|
||||||
mescrollRef.value = mescroll;
|
}
|
||||||
};
|
// 获取input 焦点跳转
|
||||||
|
const handleSearchFocus = () => {
|
||||||
|
searchShow.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
// 下拉刷新
|
const formatDateStr = (times) => {
|
||||||
const downCallback = async (mescroll) => {
|
const date = new Date(times);
|
||||||
try {
|
|
||||||
setTimeout(async ()=>{
|
let year = date.getFullYear();
|
||||||
const res = await getSalesManTaskList(1, upOption.value.page.size);
|
let month = date.getMonth() + 1;
|
||||||
cssFlag.value = false;
|
let day = date.getDate();
|
||||||
list.value = res.list;
|
|
||||||
mescroll.resetUpScroll();
|
month = month > 9 ? month : '0' + month;;
|
||||||
},500);
|
day = day > 9 ? day : '0' + day;
|
||||||
} catch (error) {
|
|
||||||
mescroll.endErr();
|
return `${year}-${month}-${day}`;
|
||||||
} finally {
|
}
|
||||||
setTimeout(async ()=>{
|
|
||||||
mescroll.endSuccess();
|
// 搜索完返回处理
|
||||||
},500);
|
const handleSearchConfirm = (param1, param2) => {
|
||||||
}
|
// console.log(param1,param2)
|
||||||
}
|
notictTypeCheck.value = param1.value;
|
||||||
// 上拉加载更多
|
inputval.value = param2.value || '';
|
||||||
const upCallback = async (mescroll) => {
|
searchValue.value = param2.value;
|
||||||
try {
|
// 重置mescroll触发刷新
|
||||||
setTimeout(async ()=>{
|
if (mescrollRef.value) {
|
||||||
const res = await getSalesManTaskList(mescroll.num, mescroll.size);
|
mescrollRef.value.resetUpScroll();
|
||||||
if (mescroll.num === 1) {
|
}
|
||||||
list.value = res.list;
|
searchShow.value = false;
|
||||||
} else {
|
}
|
||||||
list.value.push(...res.list);
|
|
||||||
}
|
|
||||||
mescroll.endBySize(res.list.length, res.total);
|
|
||||||
},500);
|
|
||||||
} catch (error) {
|
|
||||||
mescroll.endErr();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取数据列表
|
const mescrollRef = ref(null);
|
||||||
const getSalesManTaskList = (pageIndex, pageSize) => {
|
const upOption = ref({
|
||||||
return new Promise(async (resolve) => {
|
page: {
|
||||||
let param = {
|
num: 0,
|
||||||
pageIndex,
|
size: 10
|
||||||
pageSize
|
},
|
||||||
}
|
noMoreSize: 5,
|
||||||
|
empty: {
|
||||||
|
tip: '~ 空空如也 ~',
|
||||||
|
icon: "../../../../static/images/mescroll-empty.png"
|
||||||
|
},
|
||||||
|
textLoading: '加载中...',
|
||||||
|
textNoMore: '已经到底了'
|
||||||
|
});
|
||||||
|
|
||||||
let res = await SalesManTaskList(param);
|
const downOption = ref({
|
||||||
resolve({
|
auto: true,
|
||||||
list: res.list,
|
textInOffset: '下拉刷新',
|
||||||
total: res.totalCount
|
textOutOffset: '释放更新',
|
||||||
});
|
textLoading: '刷新中...'
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
let cssFlag = ref(false); //控制样式
|
||||||
|
const mescrollInit = (mescroll) => {
|
||||||
|
cssFlag.value = true;
|
||||||
|
mescrollRef.value = mescroll;
|
||||||
|
};
|
||||||
|
|
||||||
// 跳转到详情
|
// 下拉刷新
|
||||||
let handleDetail=(item)=>{
|
const downCallback = async (mescroll) => {
|
||||||
uni.navigateTo({
|
try {
|
||||||
url: "/pages/business/CRM/visitorReportDetail?id="+item.id
|
setTimeout(async () => {
|
||||||
})
|
const res = await getSalesManTaskList(1, upOption.value.page.size);
|
||||||
}
|
cssFlag.value = false;
|
||||||
|
list.value = res.list;
|
||||||
|
mescroll.resetUpScroll();
|
||||||
|
}, 500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
} finally {
|
||||||
|
setTimeout(async () => {
|
||||||
|
mescroll.endSuccess();
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 上拉加载更多
|
||||||
|
const upCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
setTimeout(async () => {
|
||||||
|
const res = await getSalesManTaskList(mescroll.num, mescroll.size,
|
||||||
|
inputval.value);
|
||||||
|
if (mescroll.num === 1) {
|
||||||
|
list.value = res.list;
|
||||||
|
} else {
|
||||||
|
list.value.push(...res.list);
|
||||||
|
}
|
||||||
|
mescroll.endBySize(res.list.length, res.total);
|
||||||
|
}, 500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数据列表
|
||||||
|
const getSalesManTaskList = (pageNum, pageSize) => {
|
||||||
|
return new Promise(async (resolve) => {
|
||||||
|
let param = {
|
||||||
|
pageNum,
|
||||||
|
pageSize,
|
||||||
|
// 添加搜索条件参数
|
||||||
|
taskName: inputval.value
|
||||||
|
}
|
||||||
|
let res = await SalesManTaskList(param);
|
||||||
|
resolve({
|
||||||
|
list: res.rows,
|
||||||
|
total: res.total
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showDetail(item) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: "/pages/business/CRM/scheduler/taskViewingDetail?data=" + encodeURIComponent(
|
||||||
|
JSON
|
||||||
|
.stringify(item))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onUnload(() => {
|
||||||
|
uni.$off('updateStatus')
|
||||||
|
})
|
||||||
|
|
||||||
|
const markVisited = (informationId) => {
|
||||||
|
const newList = [...list.value].map(item => {
|
||||||
|
if (item.informationId == informationId) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
myselfBrowsing: 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
list.value = newList;
|
||||||
|
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.all-body {
|
.all-body {
|
||||||
/* #ifdef APP-PLUS */
|
/* #ifdef APP-PLUS */
|
||||||
top: 150rpx;
|
top: 150rpx;
|
||||||
height: calc(100vh - 75px);
|
height: calc(100vh - 75px);
|
||||||
/* #endif */
|
/* #endif */
|
||||||
/* #ifndef APP-PLUS */
|
/* #ifndef APP-PLUS */
|
||||||
top:120rpx;
|
top: 120rpx;
|
||||||
height: calc(100vh);
|
height: calc(100vh);
|
||||||
/* #endif */
|
/* #endif */
|
||||||
}
|
}
|
||||||
.search{
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.search .btn-search{
|
|
||||||
border:none;
|
|
||||||
background: none;
|
|
||||||
line-height: normal;
|
|
||||||
color:#fff;
|
|
||||||
line-height: 56rpx !important;
|
|
||||||
padding:10rpx 0 0;
|
|
||||||
text-align: left;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.search .btn-search::after{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.search .custom-search{
|
|
||||||
width:80%;
|
|
||||||
|
|
||||||
}
|
.search {
|
||||||
.search .custom-search.uni-searchbar{
|
display: flex;
|
||||||
padding-right:0 !important;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.scroll-h{
|
.search .btn-search {
|
||||||
/* #ifdef APP-PLUS */
|
border: none;
|
||||||
height: calc(100vh - 120px);
|
background: none;
|
||||||
/* #endif */
|
line-height: normal;
|
||||||
/* #ifndef APP-PLUS */
|
color: #fff;
|
||||||
height: calc(100vh - 110px);
|
line-height: 56rpx !important;
|
||||||
/* #endif */
|
padding: 10rpx 0 0;
|
||||||
}
|
text-align: left;
|
||||||
.white-bg{
|
cursor: pointer;
|
||||||
padding-bottom:10rpx;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
.search .btn-search::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .custom-search {
|
||||||
|
width: 80%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .custom-search.uni-searchbar {
|
||||||
|
padding-right: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-h {
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height: calc(100vh - 120px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 110px);
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg {
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border: none;
|
||||||
|
flex: 1;
|
||||||
|
height: 70rpx;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
padding-left: 20rpx;
|
||||||
|
border-radius: 32.5rpx;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
|
||||||
|
.search_icon {
|
||||||
|
width: 30rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
margin-right: 22rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 16rpx;
|
||||||
|
padding-right: 16rpx;
|
||||||
|
border-right: 2rpx solid #D4D4D4;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-size: 13px;
|
||||||
|
margin-left: 10rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
image {
|
||||||
|
margin-top: 4rpx;
|
||||||
|
width: 20rpx;
|
||||||
|
height: 11rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop {
|
||||||
|
position: absolute;
|
||||||
|
top: 50rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
box-shadow: 0px 0px 40rpx 0px rgba(59, 59, 59, 0.2);
|
||||||
|
border-radius: 12rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx;
|
||||||
|
z-index: 100;
|
||||||
|
max-height: 566rpx;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-family: PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333333;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin: 10rpx 0;
|
||||||
|
line-height: 56rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop_arrow {
|
||||||
|
position: absolute;
|
||||||
|
top: 48rpx;
|
||||||
|
z-index: 999;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
left: 68rpx;
|
||||||
|
top: -26rpx;
|
||||||
|
border: 14rpx solid #fff;
|
||||||
|
border-color: transparent transparent #fff transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
<view class="con-body">
|
<view class="con-body">
|
||||||
<view class="con-bg">
|
<view class="con-bg">
|
||||||
<!-- 头部 -->
|
<!-- 头部 -->
|
||||||
<customHeader ref="customHeaderRef" :title="'任务计划新增'" :leftFlag="true" :rightFlag="true">
|
<customHeader ref="customHeaderRef" :title="'任务计划新增'" :leftFlag="true"
|
||||||
|
:rightFlag="true">
|
||||||
<template #right>
|
<template #right>
|
||||||
<view class="head-right" @click="submitForm">
|
<view class="head-right" @click="submitForm">
|
||||||
<uni-icons custom-prefix="iconfont" type="icon-phonebaocun" size="22"
|
<uni-icons custom-prefix="iconfont" type="icon-phonebaocun" size="22"
|
||||||
@@ -18,45 +19,57 @@
|
|||||||
<view class="white-bg">
|
<view class="white-bg">
|
||||||
<view class="form-con">
|
<view class="form-con">
|
||||||
<uni-forms ref="formRef" :model="formData" :rules="rules" label-width="100px">
|
<uni-forms ref="formRef" :model="formData" :rules="rules" label-width="100px">
|
||||||
<uni-forms-item label="标签属性" name="cusName" class="f-c-right">
|
<uni-forms-item label="主线任务" name="taskName" class="f-c-right">
|
||||||
<view
|
<view class="form-item-container">
|
||||||
@click="chooseCustomer"
|
<text class="name">{{ formData.taskName}}</text>
|
||||||
class="form-item-container"
|
</view>
|
||||||
>
|
|
||||||
<text class="name">{{ formData.cusName || '点击选择主线任务' }}</text>
|
|
||||||
</view>
|
|
||||||
</uni-forms-item>
|
</uni-forms-item>
|
||||||
<uni-forms-item label="计划内容" name="opportunityType" class="f-c-right">
|
<uni-forms-item label="计划内容" name="planContent" class="f-c-right">
|
||||||
<picker @change="onOpportunityTypeChange" :value="opportunityTypeIndex" :range="array"
|
<picker @change="onPlanContentChange" :value="planContentIndex"
|
||||||
:range-key="'name'">
|
:range="array" :range-key="'name'">
|
||||||
<view class="picker">
|
<view class="picker">
|
||||||
{{ array[opportunityTypeIndex]?.name || '请选择计划内容' }}
|
{{ array[planContentIndex]?.name || '请选择计划内容' }}
|
||||||
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
</picker>
|
</picker>
|
||||||
</uni-forms-item>
|
</uni-forms-item>
|
||||||
<uni-forms-item label="计划开始时间" name="plannedStartTime" class="f-c-right">
|
<uni-forms-item label="计划开始时间" name="plannedStartTime" class="f-c-right">
|
||||||
<picker mode="date" :value="formData.plannedStartTime" @change="onStartTimeChange">
|
<picker mode="date" :value="formData.plannedStartTime"
|
||||||
|
@change="onStartTimeChange">
|
||||||
<view class="picker">
|
<view class="picker">
|
||||||
{{ formData.plannedStartTime || '请选择计划开始时间' }}
|
{{ formData.plannedStartTime || '请选择计划开始时间' }}
|
||||||
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
</picker>
|
</picker>
|
||||||
</uni-forms-item>
|
</uni-forms-item>
|
||||||
<uni-forms-item label="计划完成时间" name="plannedCompTime" class="f-c-right">
|
<uni-forms-item label="计划完成时间" name="plannedCompTime" class="f-c-right">
|
||||||
<picker mode="date" :value="formData.plannedCompTime" @change="onCompTimeChange">
|
<picker mode="date" :value="formData.plannedCompTime"
|
||||||
|
@change="onCompTimeChange">
|
||||||
<view class="picker">
|
<view class="picker">
|
||||||
{{ formData.plannedCompTime || '请选择计划完成时间' }}
|
{{ formData.plannedCompTime || '请选择计划完成时间' }}
|
||||||
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
</picker>
|
</picker>
|
||||||
</uni-forms-item>
|
</uni-forms-item>
|
||||||
<uni-forms-item label="内容描述" name="understandTheWay"
|
<uni-forms-item label="次数" name="num">
|
||||||
|
<uni-number-box v-model="formData.num"
|
||||||
|
style="float: right;margin-right: 10rpx;margin-top: 15rpx;"></uni-number-box>
|
||||||
|
</uni-forms-item>
|
||||||
|
<uni-forms-item label="频率" name="frequency" class="f-c-right">
|
||||||
|
<picker @change="onFrequencyChange" :value="frequencyIndex"
|
||||||
|
:range="arrayFrequency" :range-key="'name'">
|
||||||
|
<view class="picker">
|
||||||
|
{{ arrayFrequency[frequencyIndex]?.name || '请选择频率' }}
|
||||||
|
<uni-icons type="right" size="20" color="#A0A0A0"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</picker>
|
||||||
|
</uni-forms-item>
|
||||||
|
<uni-forms-item label="内容描述" name="description"
|
||||||
class="uni-forms-item is-direction-top is-top">
|
class="uni-forms-item is-direction-top is-top">
|
||||||
<uni-easyinput type="textarea" autoHeight v-model="formData.understandTheWay"
|
<uni-easyinput type="textarea" autoHeight v-model="formData.description"
|
||||||
placeholder="请输入内容描述" class="form-texarea" />
|
placeholder="请输入内容描述" class="form-texarea" />
|
||||||
</uni-forms-item>
|
</uni-forms-item>
|
||||||
|
|
||||||
</uni-forms>
|
</uni-forms>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -66,45 +79,48 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import {
|
||||||
ref, onMounted, reactive, onUnmounted, computed
|
ref,
|
||||||
|
onMounted,
|
||||||
|
reactive,
|
||||||
|
onUnmounted,
|
||||||
|
computed
|
||||||
} from 'vue'
|
} from 'vue'
|
||||||
import customHeader from '@/components/customHeader.vue'
|
|
||||||
import {
|
import {
|
||||||
getGuestList
|
onLoad
|
||||||
} from '@/api/business.js'
|
} from '@dcloudio/uni-app'
|
||||||
import { isEmpty } from '@/utils/validate.js'
|
|
||||||
import {crmMarketInformationAdd } from '@/api/crm/api_ys.js'
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
|
||||||
|
import {
|
||||||
let customerUser = reactive({})
|
isEmpty
|
||||||
// 客户相关
|
} from '@/utils/validate.js'
|
||||||
const guestList = ref([])
|
import {
|
||||||
|
taskPlanAdd
|
||||||
|
} from '@/api/crm/api_ys.js'
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
cusId: null,
|
cusId: null,
|
||||||
cusName: null,
|
taskName: null,
|
||||||
opportunityType: "", // 机会类型
|
planContent: "", // 机会类型
|
||||||
plannedStartTime: "", // 计划开始时间
|
plannedStartTime: "", // 计划开始时间
|
||||||
plannedCompTime: "", // 计划完成时间
|
plannedCompTime: "", // 计划完成时间
|
||||||
understandTheWay: "", // 了解途径
|
description: "", // 内容描述
|
||||||
opportunityDescription: "", // 机会描述
|
num: "", // 次数
|
||||||
opportunityStatus: "", // 机会所处状态
|
})
|
||||||
predictedAmount: "", // 预测金额或情况
|
|
||||||
competitionSituation: "", // 竞争情况
|
onLoad((options) => {
|
||||||
remark: "", // 备注
|
if (options.data) {
|
||||||
picture: "", // 图片
|
let mainData = JSON.parse(decodeURIComponent(options.data))
|
||||||
informationType: "市场机会" // 信息类型
|
formData.value.taskName = mainData.mainTaskName
|
||||||
|
formData.value.taskId = mainData.taskId
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
const rules = {
|
const rules = {
|
||||||
cusName: {
|
planContent: {
|
||||||
rules: [{
|
|
||||||
required: true,
|
|
||||||
errorMessage: '请选择主线任务'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
opportunityType: {
|
|
||||||
rules: [{
|
rules: [{
|
||||||
required: true,
|
required: true,
|
||||||
errorMessage: '请选择计划内容'
|
errorMessage: '请选择计划内容'
|
||||||
@@ -117,10 +133,9 @@
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
plannedCompTime: {
|
plannedCompTime: {
|
||||||
rules: [
|
rules: [{
|
||||||
{
|
|
||||||
required: true,
|
required: true,
|
||||||
errorMessage: '请选择计划完成时间'
|
errorMessage: '请选择计划完成时间aaa'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
validateFunction: function(rule, value, data, callback) {
|
validateFunction: function(rule, value, data, callback) {
|
||||||
@@ -130,43 +145,19 @@
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
understandTheWay: {
|
description: {
|
||||||
rules: [{
|
rules: [{
|
||||||
required: true,
|
required: true,
|
||||||
errorMessage: '请输入内容描述'
|
errorMessage: '请输入内容描述'
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
opportunityDescription: {
|
|
||||||
rules: [{
|
|
||||||
required: true,
|
|
||||||
errorMessage: '请输入机会描述'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
opportunityStatus: {
|
|
||||||
rules: [{
|
|
||||||
required: true,
|
|
||||||
errorMessage: '请输入机会所处状态'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
predictedAmount: {
|
|
||||||
rules: [{
|
|
||||||
required: true,
|
|
||||||
errorMessage: '请输入预测金额或情况'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
competitionSituation: {
|
|
||||||
rules: [{
|
|
||||||
required: true,
|
|
||||||
errorMessage: '请输入竞争情况'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
const imgList = ref([])
|
|
||||||
|
|
||||||
// picker 相关
|
// picker 相关
|
||||||
const index = ref(0)
|
const index = ref(0)
|
||||||
@@ -211,135 +202,119 @@
|
|||||||
name: '组合拳服务活动'
|
name: '组合拳服务活动'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
const form = ref({
|
|
||||||
cusId: null,
|
|
||||||
cusName: null,
|
|
||||||
opportunityType: array.value[0].name, // 机会类型
|
|
||||||
understandTheWay: "", // 了解途径
|
|
||||||
opportunityDescription: "", // 机会描述
|
|
||||||
opportunityStatus: "", // 机会所处状态
|
|
||||||
predictedAmount: "", // 预测金额或情况
|
|
||||||
competitionSituation: "", // 竞争情况
|
|
||||||
remark: "", // 备注
|
|
||||||
picture: "", // 图片
|
|
||||||
informationType: "市场机会" // 信息类型
|
|
||||||
})
|
|
||||||
|
|
||||||
// picker 选项
|
const arrayFrequency = ref([{
|
||||||
const opportunityTypeOptions = ref([{
|
|
||||||
id: 0,
|
id: 0,
|
||||||
name: '新产品需求'
|
name: '',
|
||||||
|
value: 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
name: '新客户开发'
|
name: '3天1次',
|
||||||
|
value: 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
name: '批产任务'
|
name: '7天1次',
|
||||||
|
value: 7
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
name: '新研任务'
|
name: '15天1次',
|
||||||
|
value: 15
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 4,
|
id: 4,
|
||||||
name: '二筛服务'
|
name: '30天1次',
|
||||||
},
|
value: 30
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
name: '对手失利'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
name: '其它'
|
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
const opportunityTypeIndex = ref(0)
|
|
||||||
|
const planContentIndex = ref(0)
|
||||||
|
const frequencyIndex = ref(0)
|
||||||
|
|
||||||
// 表单引用 & 客户选择器引用
|
// 表单引用 & 客户选择器引用
|
||||||
const formRef = ref(null)
|
const formRef = ref(null)
|
||||||
const customHeaderRef = ref(null)
|
const customHeaderRef = ref(null)
|
||||||
// 选择客户页面跳转
|
|
||||||
function chooseCustomer(){
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/business/CRM/marketActivity/chooseCus'
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
//定义数据接收的值
|
|
||||||
let selectedCustomer = reactive(null)
|
|
||||||
|
|
||||||
//监听时间
|
//监听时间
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 设置机会类型的默认值
|
// 设置机会类型的默认值
|
||||||
formData.value.opportunityType = array.value[0].name;
|
formData.value.planContent = array.value[0].name;
|
||||||
opportunityTypeIndex.value = 0;
|
planContentIndex.value = 0;
|
||||||
|
frequencyIndex.value = 0;
|
||||||
// 原有的监听客户选择事件
|
|
||||||
uni.$on('onCustomerSelected', handleCustomerSelected);
|
|
||||||
})
|
})
|
||||||
//取消监听
|
|
||||||
onUnmounted(() => {
|
|
||||||
uni.$off('onCustomerSelected', handleCustomerSelected)
|
|
||||||
})
|
|
||||||
|
|
||||||
//处理 接收数据
|
|
||||||
const handleCustomerSelected = (data) => {
|
|
||||||
formData.value.cusName = data.cusName
|
|
||||||
formData.value.cusId = data.cusId
|
|
||||||
console.log("收到客户数据的值:", customerUser)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 提交表单
|
// 提交表单
|
||||||
const submitForm = async () => {
|
const submitForm = async () => {
|
||||||
try {
|
try {
|
||||||
|
formData.value.planType = "0"
|
||||||
// 表单校验
|
// 表单校验
|
||||||
await formRef.value.validate()
|
await formRef.value.validate()
|
||||||
const res = await crmMarketInformationAdd(formData.value);
|
const res = await taskPlanAdd(formData.value);
|
||||||
console.log(res)
|
console.log(res)
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '提交成功',
|
title: '提交成功',
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
uni.$emit('refreshMarketList');
|
uni.$emit('refreshMarketList');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
uni.navigateBack(1);
|
uni.navigateBack(1);
|
||||||
}, 1500);
|
}, 1500);
|
||||||
|
|
||||||
console.log('表单数据:', formData.value)
|
console.log('表单数据:', formData.value)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('表单验证失败:', err)
|
console.log('表单验证失败:', err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onOpportunityTypeChange = (e) => {
|
const onPlanContentChange = (e) => {
|
||||||
opportunityTypeIndex.value = e.detail.value
|
planContentIndex.value = e.detail.value
|
||||||
console.log('opportunityTypeIndex:', array.value[e.detail.value]?.name)
|
formData.value.planContent = array.value[e.detail.value]?.name || ''
|
||||||
formData.value.opportunityType = array.value[e.detail.value]?.name || ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onFrequencyChange = (e) => {
|
||||||
|
frequencyIndex.value = e.detail.value
|
||||||
|
formData.value.frequency = arrayFrequency.value[e.detail.value]?.value || null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 计划开始时间变化事件
|
// 计划开始时间变化事件
|
||||||
const onStartTimeChange = (e) => {
|
const onStartTimeChange = (e) => {
|
||||||
formData.value.plannedStartTime = e.detail.value
|
const value = e.detail.value
|
||||||
|
formData.value.plannedStartTime = value
|
||||||
// 如果已选择完成时间,重新校验完成时间
|
// 如果已选择完成时间,重新校验完成时间
|
||||||
if (formData.value.plannedCompTime) {
|
|
||||||
formRef.value.validateField('plannedCompTime')
|
// Vue3 中需要手动触发验证更新
|
||||||
|
if (formRef.value) {
|
||||||
|
// 方法1:使用 setValue
|
||||||
|
formRef.value.setValue('plannedStartTime', value)
|
||||||
|
|
||||||
|
if (formData.value.plannedCompTime) {
|
||||||
|
formRef.value.validateField('plannedCompTime')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计划完成时间变化事件
|
// 计划完成时间变化事件
|
||||||
const onCompTimeChange = (e) => {
|
const onCompTimeChange = (e) => {
|
||||||
formData.value.plannedCompTime = e.detail.value
|
const value = e.detail.value
|
||||||
// 校验完成时间
|
formData.value.plannedCompTime = value
|
||||||
formRef.value.validateField('plannedCompTime')
|
|
||||||
|
// Vue3 中需要手动触发验证更新
|
||||||
|
if (formRef.value) {
|
||||||
|
// 方法1:使用 setValue
|
||||||
|
formRef.value.setValue('plannedCompTime', value)
|
||||||
|
|
||||||
|
// 校验完成时间
|
||||||
|
formRef.value.validateField('plannedCompTime')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 如果你原来在 onShow 中做了类似这样:
|
// 如果你原来在 onShow 中做了类似这样:
|
||||||
// let res = currPage.data.cusData; 判断是否传入了客户信息
|
// let res = currPage.data.cusData; 判断是否传入了客户信息
|
||||||
// 那么在 Vue3 中通常是通过路由参数或者 Vuex/Pinia 等状态管理获取
|
// 那么在 Vue3 中通常是通过路由参数或者 Vuex/Pinia 等状态管理获取
|
||||||
|
|||||||
413
src/pages/business/CRM/scheduler/taskPlanList.vue
Normal file
413
src/pages/business/CRM/scheduler/taskPlanList.vue
Normal file
@@ -0,0 +1,413 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" :title="!searchShow ? '任务计划查看' : '搜索'"
|
||||||
|
:leftFlag="true" :rightFlag="true" @back="handleBack"
|
||||||
|
:searchType="searchShow ? 1 : undefined">
|
||||||
|
<!-- <template #right v-if="!searchShow">
|
||||||
|
<view class="head-right" @click="handleRead">
|
||||||
|
<img :src="'static/images/icon-clean@2x.png'" />清除未读
|
||||||
|
</view>
|
||||||
|
</template> -->
|
||||||
|
</customHeader>
|
||||||
|
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 搜索处理 -->
|
||||||
|
<customSearch v-if="searchShow" :searchKeywords="searchText" :searchType="searchTypeObj"
|
||||||
|
:checkTypeObj="notictTypeCheck" @confirm="handleSearchConfirm">
|
||||||
|
</customSearch>
|
||||||
|
<view class="search" v-else @click="handleSearchFocus">
|
||||||
|
<view class="search-bg">
|
||||||
|
<view class="search-left">
|
||||||
|
{{ notictTypeCheck.name ? notictTypeCheck.name : '全部' }}
|
||||||
|
</view>
|
||||||
|
<view class="search-right">
|
||||||
|
<input class="uni-input" v-model="inputval" placeholder="请输入您想查询的内容"
|
||||||
|
placeholder-class="search-color" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 正文内容 -->
|
||||||
|
<!-- 分页部分 -->
|
||||||
|
<mescroll-uni v-if="!searchShow" ref="mescrollRef" @init="mescrollInit"
|
||||||
|
@down="downCallback" @up="upCallback" :up="upOption" :down="downOption"
|
||||||
|
:fixed="false" textColor="#ffffff" bgColor="#ffffff" class="scroll-h"
|
||||||
|
:class="{ 'loading-scroll': cssFlag }">
|
||||||
|
<view class="white-bg margin-bottom20" v-for="(item, index) in list" :key="index"
|
||||||
|
@click="showDetail(item)">
|
||||||
|
<view>
|
||||||
|
<view class="report-list">
|
||||||
|
<view class="title" style="font-size: 30rpx">
|
||||||
|
主线任务:{{ item.taskName }}
|
||||||
|
</view>
|
||||||
|
<view class="r-left"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
计划内容:{{ item.planContent }}
|
||||||
|
</view>
|
||||||
|
<view class="r-left"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
计划开始时间:{{ item.plannedStartTime }}
|
||||||
|
</view>
|
||||||
|
<view class="r-left"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
计划结束时间:{{ item.plannedCompTime }}
|
||||||
|
</view>
|
||||||
|
<view class="r-left"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
次数:{{ item.num }}
|
||||||
|
</view>
|
||||||
|
<view class="r-left"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
频率提醒:{{ item.reminderCount }}
|
||||||
|
</view>
|
||||||
|
<view class="r-left"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
完成状态:{{ item.completionCount }}
|
||||||
|
</view>
|
||||||
|
<view class="r-left"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
是否超时:{{ item.planStatus }}
|
||||||
|
</view>
|
||||||
|
<view class="r-left"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
审批状态:
|
||||||
|
<label v-if="item.approvalStatus == '0'" style="color: #cf0000;">{{ item.approvalStatus }}</label>
|
||||||
|
<label v-else-if="item.approvalStatus == '1'" style="color: #00cf00;">{{ item.approvalStatus }}</label>
|
||||||
|
<label v-else style="color: #60a0ff;">{{ item.approvalStatus }}</label>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</mescroll-uni>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
onMounted,
|
||||||
|
watch
|
||||||
|
} from 'vue'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import customSearch from '@/components/customSearch.vue'
|
||||||
|
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||||
|
import {
|
||||||
|
getNavBarPaddingTop
|
||||||
|
} from '@/utils/system.js'
|
||||||
|
|
||||||
|
import {
|
||||||
|
TaskPlanList
|
||||||
|
} from '@/api/crm/api_ys.js'
|
||||||
|
|
||||||
|
import {
|
||||||
|
onLoad,
|
||||||
|
onShow,
|
||||||
|
onUnload,
|
||||||
|
onHide
|
||||||
|
} from '@dcloudio/uni-app'
|
||||||
|
// 获取导航栏高度用于内容区域padding
|
||||||
|
const navBarPaddingTop = ref(0);
|
||||||
|
onMounted(() => {
|
||||||
|
navBarPaddingTop.value = getNavBarPaddingTop() * 2;
|
||||||
|
uni.$on('updateStatus', markVisited)
|
||||||
|
})
|
||||||
|
// 搜索处理
|
||||||
|
let searchShow = ref(false);
|
||||||
|
let searchText = ref(undefined);
|
||||||
|
let searchTypeObj = ref({
|
||||||
|
typeId: 3,
|
||||||
|
typeName: '消息类型'
|
||||||
|
});
|
||||||
|
|
||||||
|
let notictTypeCheck = ref({}); //选中类型
|
||||||
|
|
||||||
|
// 查询列表
|
||||||
|
let list = ref([]);
|
||||||
|
// 新增状态变量存储搜索条件
|
||||||
|
const inputval = ref(''); // 搜索内容
|
||||||
|
let searchValue = ref(null)
|
||||||
|
//监视查询的内容的变化
|
||||||
|
watch(searchValue, (newValue, oldValue) => {
|
||||||
|
//变化了之后,重新查询内容
|
||||||
|
var data = {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
};
|
||||||
|
TaskPlanList(data).then(res => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
//设置列表数据
|
||||||
|
list.value = res.rows;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
onHide(() => {
|
||||||
|
searchShow.value = false;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 搜索返回操作
|
||||||
|
const handleBack = () => {
|
||||||
|
searchShow.value = false;
|
||||||
|
}
|
||||||
|
// 获取input 焦点跳转
|
||||||
|
const handleSearchFocus = () => {
|
||||||
|
searchShow.value = true;
|
||||||
|
}
|
||||||
|
// 搜索完返回处理
|
||||||
|
const handleSearchConfirm = (param1, param2) => {
|
||||||
|
// console.log(param1,param2)
|
||||||
|
notictTypeCheck.value = param1.value;
|
||||||
|
inputval.value = param2.value || '';
|
||||||
|
searchValue.value = param2.value;
|
||||||
|
// 重置mescroll触发刷新
|
||||||
|
if (mescrollRef.value) {
|
||||||
|
mescrollRef.value.resetUpScroll();
|
||||||
|
}
|
||||||
|
searchShow.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mescrollRef = ref(null);
|
||||||
|
const upOption = ref({
|
||||||
|
page: {
|
||||||
|
num: 0,
|
||||||
|
size: 10
|
||||||
|
},
|
||||||
|
noMoreSize: 5,
|
||||||
|
empty: {
|
||||||
|
tip: '~ 空空如也 ~',
|
||||||
|
icon: "../../../../static/images/mescroll-empty.png"
|
||||||
|
},
|
||||||
|
textLoading: '加载中...',
|
||||||
|
textNoMore: '已经到底了'
|
||||||
|
});
|
||||||
|
|
||||||
|
const downOption = ref({
|
||||||
|
auto: true,
|
||||||
|
textInOffset: '下拉刷新',
|
||||||
|
textOutOffset: '释放更新',
|
||||||
|
textLoading: '刷新中...'
|
||||||
|
});
|
||||||
|
|
||||||
|
let cssFlag = ref(false); //控制样式
|
||||||
|
const mescrollInit = (mescroll) => {
|
||||||
|
cssFlag.value = true;
|
||||||
|
mescrollRef.value = mescroll;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const downCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
setTimeout(async () => {
|
||||||
|
const res = await getTaskPlanList(1, upOption.value.page.size);
|
||||||
|
cssFlag.value = false;
|
||||||
|
list.value = res.list;
|
||||||
|
mescroll.resetUpScroll();
|
||||||
|
}, 500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
} finally {
|
||||||
|
setTimeout(async () => {
|
||||||
|
mescroll.endSuccess();
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 上拉加载更多
|
||||||
|
const upCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
setTimeout(async () => {
|
||||||
|
const res = await getTaskPlanList(mescroll.num, mescroll.size,
|
||||||
|
inputval.value);
|
||||||
|
if (mescroll.num === 1) {
|
||||||
|
list.value = res.list;
|
||||||
|
} else {
|
||||||
|
list.value.push(...res.list);
|
||||||
|
}
|
||||||
|
mescroll.endBySize(res.list.length, res.total);
|
||||||
|
}, 500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数据列表
|
||||||
|
const getTaskPlanList = (pageNum, pageSize) => {
|
||||||
|
return new Promise(async (resolve) => {
|
||||||
|
let param = {
|
||||||
|
pageNum,
|
||||||
|
pageSize,
|
||||||
|
// 添加搜索条件参数
|
||||||
|
searchInput: inputval.value
|
||||||
|
}
|
||||||
|
let res = await TaskPlanList(param);
|
||||||
|
resolve({
|
||||||
|
list: res.rows,
|
||||||
|
total: res.total
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showDetail(item) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: "/pages/business/CRM/scheduler/taskViewingDetail?data=" + encodeURIComponent(
|
||||||
|
JSON
|
||||||
|
.stringify(item))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onUnload(() => {
|
||||||
|
uni.$off('updateStatus')
|
||||||
|
})
|
||||||
|
|
||||||
|
const markVisited = (informationId) => {
|
||||||
|
const newList = [...list.value].map(item => {
|
||||||
|
if (item.informationId == informationId) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
myselfBrowsing: 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
list.value = newList;
|
||||||
|
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.all-body {
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
top: 150rpx;
|
||||||
|
height: calc(100vh - 75px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
top: 120rpx;
|
||||||
|
height: calc(100vh);
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.search {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .btn-search {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
line-height: normal;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 56rpx !important;
|
||||||
|
padding: 10rpx 0 0;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .btn-search::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .custom-search {
|
||||||
|
width: 80%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .custom-search.uni-searchbar {
|
||||||
|
padding-right: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-h {
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height: calc(100vh - 120px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 110px);
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg {
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border: none;
|
||||||
|
flex: 1;
|
||||||
|
height: 70rpx;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
padding-left: 20rpx;
|
||||||
|
border-radius: 32.5rpx;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
|
||||||
|
.search_icon {
|
||||||
|
width: 30rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
margin-right: 22rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 16rpx;
|
||||||
|
padding-right: 16rpx;
|
||||||
|
border-right: 2rpx solid #D4D4D4;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-size: 13px;
|
||||||
|
margin-left: 10rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
image {
|
||||||
|
margin-top: 4rpx;
|
||||||
|
width: 20rpx;
|
||||||
|
height: 11rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop {
|
||||||
|
position: absolute;
|
||||||
|
top: 50rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
box-shadow: 0px 0px 40rpx 0px rgba(59, 59, 59, 0.2);
|
||||||
|
border-radius: 12rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx;
|
||||||
|
z-index: 100;
|
||||||
|
max-height: 566rpx;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-family: PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333333;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin: 10rpx 0;
|
||||||
|
line-height: 56rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop_arrow {
|
||||||
|
position: absolute;
|
||||||
|
top: 48rpx;
|
||||||
|
z-index: 999;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
left: 68rpx;
|
||||||
|
top: -26rpx;
|
||||||
|
border: 14rpx solid #fff;
|
||||||
|
border-color: transparent transparent #fff transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
309
src/pages/business/CRM/scheduler/taskPlanReview.vue
Normal file
309
src/pages/business/CRM/scheduler/taskPlanReview.vue
Normal file
@@ -0,0 +1,309 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<customHeader ref="customHeaderRef" :title="'任务计划审批'" :leftFlag="true">
|
||||||
|
</customHeader>
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<view style="height:50rpx"></view>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="tabs-container">
|
||||||
|
<view class="search">
|
||||||
|
<uni-search-bar class="custom-search" radius="28" placeholder="任务名称"
|
||||||
|
clearButton="auto" cancelButton="none" bgColor="#6FA2F8"
|
||||||
|
textColor="#ffffff" v-model="searchValue" />
|
||||||
|
<button type="default" @click="handleSearch" size="mini"
|
||||||
|
class="btn-search">查询</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="tabs-scorll">
|
||||||
|
<view class="tabs-header">
|
||||||
|
<view v-for="(tab, index) in tabHeaderList" :key="index"
|
||||||
|
:class="['tab-item-main', { 'active': activeTabHeader === index }]"
|
||||||
|
@click="switchTabHeader(index)">
|
||||||
|
{{ tab }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="white-bg-2" v-for="item in detailList">
|
||||||
|
<view class="report-list" @click="showDetail(item)">
|
||||||
|
<view class="report-list">
|
||||||
|
<view class="title" style="font-size: 30rpx;margin-top: 20rpx;">
|
||||||
|
{{ item.typeval == '1' ? '全天' : item.typeval == '2' ? '前半个班次' : '后半个班次' }}
|
||||||
|
|
||||||
|
<label v-if="item.applyType == '请假'"
|
||||||
|
style="float: right;color: #03ca03;">
|
||||||
|
{{ item.applyType }}</label>
|
||||||
|
<label v-if="item.applyType == '销假'"
|
||||||
|
style="float: right;color: #eaa303;">
|
||||||
|
{{ item.applyType }}</label>
|
||||||
|
</view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">姓名</view>
|
||||||
|
<view class="r-right">{{ item.applyUserName }} </view>
|
||||||
|
</view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">{{ item.applyType }}日期</view>
|
||||||
|
<view class="r-right">{{ item.startDate }} 至 {{ item.endDate }}
|
||||||
|
( <label v-if="item.applyType == '请假'"
|
||||||
|
style="color: #03ca03;">
|
||||||
|
{{ item.days.replace('.0', '') }}天</label>
|
||||||
|
<label v-if="item.applyType == '销假'"
|
||||||
|
style="color: #eaa303;">
|
||||||
|
{{ item.days.replace('.0', '') }}天</label> )
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">详细说明</view>
|
||||||
|
<view v-if="item.reason && item.reason.length <= 18"
|
||||||
|
class="r-right">{{ item.reason
|
||||||
|
}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="r-list" style="margin-top: -30rpx;"
|
||||||
|
v-if="item.reason && item.reason.length > 18">
|
||||||
|
<view class="r-right">{{ item.reason }}</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view class="border-bottom" style="margin: 20rpx 0;"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="uni-pagination-box"><uni-pagination show-icon :page-size="pageSize"
|
||||||
|
:current="pageCurrent" :total="total" @change="change" /></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
onMounted,
|
||||||
|
reactive
|
||||||
|
} from 'vue'
|
||||||
|
import {
|
||||||
|
onShow
|
||||||
|
} from '@dcloudio/uni-app'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import {
|
||||||
|
getNavBarPaddingTop
|
||||||
|
} from '@/utils/system.js'
|
||||||
|
|
||||||
|
import {
|
||||||
|
getMyReviewList
|
||||||
|
} from '@/api/crm/api_ys.js'
|
||||||
|
|
||||||
|
|
||||||
|
// 获取导航栏高度用于内容区域padding
|
||||||
|
const navBarPaddingTop = ref(0);
|
||||||
|
onMounted(() => {
|
||||||
|
navBarPaddingTop.value = getNavBarPaddingTop() * 2;
|
||||||
|
getlist();
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
uni.$on('isRefresh', function() {
|
||||||
|
isRefresh.value = true
|
||||||
|
getlist();
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
let isRefresh = ref(false)
|
||||||
|
|
||||||
|
let searchValue = ref(null)
|
||||||
|
// 查询搜索跳转
|
||||||
|
let handleSearch = () => {
|
||||||
|
isRefresh.value = true
|
||||||
|
getlist();
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageSize = ref(4);
|
||||||
|
const pageCurrent = ref(1);
|
||||||
|
const loading = ref(false);
|
||||||
|
let tabHeaderList = ref(['待审核', '已审核'])
|
||||||
|
|
||||||
|
let total = ref(0);
|
||||||
|
const totalAll = ref(0);
|
||||||
|
const totalReject = ref(0);
|
||||||
|
const totalPass = ref(0);
|
||||||
|
|
||||||
|
|
||||||
|
let activeTab = ref(0);
|
||||||
|
let activeTabHeader = ref(0);
|
||||||
|
|
||||||
|
let detailList = ref([])
|
||||||
|
let detailLists = ref([])
|
||||||
|
|
||||||
|
//驳回
|
||||||
|
let rejectList = ref([])
|
||||||
|
//通过
|
||||||
|
let passList = ref([])
|
||||||
|
//待审批
|
||||||
|
let reviewList = ref([])
|
||||||
|
|
||||||
|
const getlist = async () => {
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
|
let res = await getMyReviewList({
|
||||||
|
applyUserName: searchValue.value
|
||||||
|
});
|
||||||
|
detailLists.value = res.rows;
|
||||||
|
|
||||||
|
rejectList.value = res.rows.filter(t => t.status == '驳回' && t.reviewerIdR != null)
|
||||||
|
passList.value = res.rows.filter(t => t.status != '驳回' && t.reviewerIdR != null)
|
||||||
|
|
||||||
|
reviewList.value = res.rows.filter(t => t.reviewerIdR != null)
|
||||||
|
|
||||||
|
total.value = res.total
|
||||||
|
|
||||||
|
totalReject.value = rejectList.value.length
|
||||||
|
totalPass.value = passList.value.length
|
||||||
|
|
||||||
|
totalAll.value = reviewList.value.length
|
||||||
|
|
||||||
|
if (isRefresh.value == false) {
|
||||||
|
switchTabHeader(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const switchTabHeader = (index) => {
|
||||||
|
isRefresh.value = false
|
||||||
|
activeTabHeader.value = index
|
||||||
|
|
||||||
|
change({
|
||||||
|
current: 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页触发
|
||||||
|
let change = (e) => {
|
||||||
|
pageCurrent.value = e.current
|
||||||
|
|
||||||
|
let end = pageSize.value * e.current
|
||||||
|
let start = end - pageSize.value
|
||||||
|
|
||||||
|
if (activeTabHeader.value == 0) {
|
||||||
|
detailList.value = passList.value.slice(start, end)
|
||||||
|
total.value = totalPass.value
|
||||||
|
} else if (activeTabHeader.value == 1) {
|
||||||
|
detailList.value = rejectList.value.slice(start, end)
|
||||||
|
total.value = totalReject.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转
|
||||||
|
let showDetail = (item) => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: "/pages/business/CRM/leave/reviewDetail?data=" + encodeURIComponent(JSON
|
||||||
|
.stringify(item))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.apply-row {
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-bottom {
|
||||||
|
margin: 5px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs-header {
|
||||||
|
display: flex;
|
||||||
|
height: 80rpx;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1rpx solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active {
|
||||||
|
color: #007AFF;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 200rpx;
|
||||||
|
height: 4rpx;
|
||||||
|
background-color: #007AFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item-main {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item-main.active {
|
||||||
|
color: #007AFF;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item-main.active::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 300rpx;
|
||||||
|
height: 4rpx;
|
||||||
|
background-color: #007AFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.report-list .r-list) {
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .btn-search {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
line-height: normal;
|
||||||
|
color: #666;
|
||||||
|
line-height: 56rpx !important;
|
||||||
|
padding: 10rpx 0 0;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .btn-search::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .custom-search {
|
||||||
|
width: 80%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .custom-search.uni-searchbar {
|
||||||
|
padding-right: 0 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
393
src/pages/business/CRM/scheduler/taskViewingDetail.vue
Normal file
393
src/pages/business/CRM/scheduler/taskViewingDetail.vue
Normal file
@@ -0,0 +1,393 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" :title="!searchShow ? '主线任务列表' : '搜索'"
|
||||||
|
:leftFlag="true" :rightFlag="true" @back="handleBack"
|
||||||
|
:searchType="searchShow ? 1 : undefined">
|
||||||
|
<!-- <template #right v-if="!searchShow">
|
||||||
|
<view class="head-right" @click="handleRead">
|
||||||
|
<img :src="'static/images/icon-clean@2x.png'" />清除未读
|
||||||
|
</view>
|
||||||
|
</template> -->
|
||||||
|
</customHeader>
|
||||||
|
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 正文内容 -->
|
||||||
|
<!-- 分页部分 -->
|
||||||
|
<mescroll-uni v-if="!searchShow" ref="mescrollRef" @init="mescrollInit"
|
||||||
|
@down="downCallback" @up="upCallback" :up="upOption" :down="downOption"
|
||||||
|
:fixed="false" textColor="#ffffff" bgColor="#ffffff" class="scroll-h"
|
||||||
|
:class="{ 'loading-scroll': cssFlag }">
|
||||||
|
<view class="white-bg margin-bottom20" v-for="(item, index) in list" :key="index">
|
||||||
|
<view>
|
||||||
|
<view class="report-list">
|
||||||
|
<view class="title" style="font-size: 30rpx">
|
||||||
|
主线任务内容:{{ item.mainTaskName }}
|
||||||
|
</view>
|
||||||
|
<view class="r-left"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="r-left"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
计划开始时间:{{ formatDateStr(item.mainTaskStartTime) }}
|
||||||
|
</view>
|
||||||
|
<view class="r-left"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
计划结束时间:{{ formatDateStr(item.mainTaskEndTime) }}
|
||||||
|
</view>
|
||||||
|
<view style="display: flex;align-items: center;">
|
||||||
|
<view class="r-left"
|
||||||
|
style="width:80%;font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
完成状态:{{ item.mainTaskStatus }}
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<uni-icons type="plus-filled" size="30" color="#38A6FF"
|
||||||
|
@click="showDetail(item)"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="right"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
完成状态:{{ item.mainTaskStatus }}
|
||||||
|
</view>
|
||||||
|
<view class="r-left"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
是否超期:{{ item.mainTaskIsOverdue }}
|
||||||
|
</view>
|
||||||
|
<view class="r-left"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
绩效分:{{ item.mainTaskScore_JX }}
|
||||||
|
</view>
|
||||||
|
<view class="r-left"
|
||||||
|
style="font-size: 25rpx;font-weight: 500;margin-top: 10rpx;">
|
||||||
|
能力分:{{ item.mainTaskScore_NL }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</mescroll-uni>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
onMounted,
|
||||||
|
watch
|
||||||
|
} from 'vue'
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import customSearch from '@/components/customSearch.vue'
|
||||||
|
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||||
|
import {
|
||||||
|
getNavBarPaddingTop
|
||||||
|
} from '@/utils/system.js'
|
||||||
|
|
||||||
|
import {
|
||||||
|
SalesManTaskDetailList
|
||||||
|
} from '@/api/crm/api_ys.js'
|
||||||
|
|
||||||
|
import {
|
||||||
|
onLoad,
|
||||||
|
onShow,
|
||||||
|
onUnload,
|
||||||
|
onHide
|
||||||
|
} from '@dcloudio/uni-app'
|
||||||
|
// 获取导航栏高度用于内容区域padding
|
||||||
|
const navBarPaddingTop = ref(0);
|
||||||
|
let mainTaskId = ref("");
|
||||||
|
onMounted(() => {
|
||||||
|
navBarPaddingTop.value = getNavBarPaddingTop() * 2;
|
||||||
|
uni.$on('updateStatus', markVisited)
|
||||||
|
})
|
||||||
|
|
||||||
|
let mainData = ref();
|
||||||
|
onLoad((options) => {
|
||||||
|
if (options.data) {
|
||||||
|
mainData = JSON.parse(decodeURIComponent(options.data))
|
||||||
|
mainTaskId.value = mainData.mainTaskId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 搜索处理
|
||||||
|
let searchShow = ref(false);
|
||||||
|
|
||||||
|
// 查询列表
|
||||||
|
let list = ref([]);
|
||||||
|
// 新增状态变量存储搜索条件
|
||||||
|
const inputval = ref(''); // 搜索内容
|
||||||
|
|
||||||
|
onHide(() => {
|
||||||
|
searchShow.value = false;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 搜索返回操作
|
||||||
|
const handleBack = () => {
|
||||||
|
searchShow.value = false;
|
||||||
|
}
|
||||||
|
// 获取input 焦点跳转
|
||||||
|
const handleSearchFocus = () => {
|
||||||
|
searchShow.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatDateStr = (times) => {
|
||||||
|
const date = new Date(times);
|
||||||
|
|
||||||
|
let year = date.getFullYear();
|
||||||
|
let month = date.getMonth() + 1;
|
||||||
|
let day = date.getDate();
|
||||||
|
|
||||||
|
month = month > 9 ? month : '0' + month;;
|
||||||
|
day = day > 9 ? day : '0' + day;
|
||||||
|
|
||||||
|
return `${year}-${month}-${day}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mescrollRef = ref(null);
|
||||||
|
const upOption = ref({
|
||||||
|
page: {
|
||||||
|
num: 0,
|
||||||
|
size: 10
|
||||||
|
},
|
||||||
|
noMoreSize: 5,
|
||||||
|
empty: {
|
||||||
|
tip: '~ 空空如也 ~',
|
||||||
|
icon: "../../../../static/images/mescroll-empty.png"
|
||||||
|
},
|
||||||
|
textLoading: '加载中...',
|
||||||
|
textNoMore: '已经到底了'
|
||||||
|
});
|
||||||
|
|
||||||
|
const downOption = ref({
|
||||||
|
auto: true,
|
||||||
|
textInOffset: '下拉刷新',
|
||||||
|
textOutOffset: '释放更新',
|
||||||
|
textLoading: '刷新中...'
|
||||||
|
});
|
||||||
|
|
||||||
|
let cssFlag = ref(false); //控制样式
|
||||||
|
const mescrollInit = (mescroll) => {
|
||||||
|
cssFlag.value = true;
|
||||||
|
mescrollRef.value = mescroll;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const downCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
setTimeout(async () => {
|
||||||
|
const res = await getSalesManTaskDetailList(1, upOption.value.page
|
||||||
|
.size);
|
||||||
|
cssFlag.value = false;
|
||||||
|
list.value = res.list;
|
||||||
|
mescroll.resetUpScroll();
|
||||||
|
}, 500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
} finally {
|
||||||
|
setTimeout(async () => {
|
||||||
|
mescroll.endSuccess();
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 上拉加载更多
|
||||||
|
const upCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
setTimeout(async () => {
|
||||||
|
const res = await getSalesManTaskDetailList(mescroll.num, mescroll
|
||||||
|
.size,
|
||||||
|
inputval.value);
|
||||||
|
if (mescroll.num === 1) {
|
||||||
|
list.value = res.list;
|
||||||
|
} else {
|
||||||
|
list.value.push(...res.list);
|
||||||
|
}
|
||||||
|
mescroll.endBySize(res.list.length, res.total);
|
||||||
|
}, 500);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数据列表
|
||||||
|
const getSalesManTaskDetailList = (pageNum, pageSize) => {
|
||||||
|
return new Promise(async (resolve) => {
|
||||||
|
let param = {
|
||||||
|
pageNum,
|
||||||
|
pageSize,
|
||||||
|
// 添加搜索条件参数
|
||||||
|
mainTaskId: mainTaskId.value
|
||||||
|
}
|
||||||
|
let res = await SalesManTaskDetailList(param);
|
||||||
|
resolve({
|
||||||
|
list: res.rows,
|
||||||
|
total: res.total
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showDetail(item) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: "/pages/business/CRM/scheduler/taskPlanAdded?data=" + encodeURIComponent(
|
||||||
|
JSON
|
||||||
|
.stringify(item))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onUnload(() => {
|
||||||
|
uni.$off('updateStatus')
|
||||||
|
})
|
||||||
|
|
||||||
|
const markVisited = (informationId) => {
|
||||||
|
const newList = [...list.value].map(item => {
|
||||||
|
if (item.informationId == informationId) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
myselfBrowsing: 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
list.value = newList;
|
||||||
|
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.all-body {
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
top: 150rpx;
|
||||||
|
height: calc(100vh - 75px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
top: 120rpx;
|
||||||
|
height: calc(100vh);
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.search {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .btn-search {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
line-height: normal;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 56rpx !important;
|
||||||
|
padding: 10rpx 0 0;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .btn-search::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .custom-search {
|
||||||
|
width: 80%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.search .custom-search.uni-searchbar {
|
||||||
|
padding-right: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-h {
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height: calc(100vh - 120px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 110px);
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg {
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border: none;
|
||||||
|
flex: 1;
|
||||||
|
height: 70rpx;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
padding-left: 20rpx;
|
||||||
|
border-radius: 32.5rpx;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
|
||||||
|
.search_icon {
|
||||||
|
width: 30rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
margin-right: 22rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 16rpx;
|
||||||
|
padding-right: 16rpx;
|
||||||
|
border-right: 2rpx solid #D4D4D4;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-size: 13px;
|
||||||
|
margin-left: 10rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
image {
|
||||||
|
margin-top: 4rpx;
|
||||||
|
width: 20rpx;
|
||||||
|
height: 11rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop {
|
||||||
|
position: absolute;
|
||||||
|
top: 50rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
box-shadow: 0px 0px 40rpx 0px rgba(59, 59, 59, 0.2);
|
||||||
|
border-radius: 12rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx;
|
||||||
|
z-index: 100;
|
||||||
|
max-height: 566rpx;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-family: PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333333;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin: 10rpx 0;
|
||||||
|
line-height: 56rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop_arrow {
|
||||||
|
position: absolute;
|
||||||
|
top: 48rpx;
|
||||||
|
z-index: 999;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
left: 68rpx;
|
||||||
|
top: -26rpx;
|
||||||
|
border: 14rpx solid #fff;
|
||||||
|
border-color: transparent transparent #fff transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -85,7 +85,7 @@ onShow(()=>{
|
|||||||
try {
|
try {
|
||||||
showLoading("加载中...")
|
showLoading("加载中...")
|
||||||
getList();
|
getList();
|
||||||
// getTaskCount();
|
getTaskCount();
|
||||||
hideLoading();
|
hideLoading();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
hideLoading();
|
hideLoading();
|
||||||
@@ -164,7 +164,7 @@ const downOption = ref({
|
|||||||
const downCallback = async (mescroll) => {
|
const downCallback = async (mescroll) => {
|
||||||
try {
|
try {
|
||||||
setTimeout(async ()=>{
|
setTimeout(async ()=>{
|
||||||
// getTaskCount();
|
getTaskCount();
|
||||||
getList();
|
getList();
|
||||||
// mescroll.resetUpScroll();
|
// mescroll.resetUpScroll();
|
||||||
},500);
|
},500);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
inputText: 'testtesttesttesttestfdsf'
|
inputText: 'testtesttesttesttestfdsftttg'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
|||||||
@@ -103,10 +103,13 @@
|
|||||||
</view>
|
</view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<!-- #ifndef APP-PLUS -->
|
<!-- #ifndef APP-PLUS -->
|
||||||
<view class="r-right r-active">
|
<view class="r-right r-active" v-if="item.resultContent" >
|
||||||
<img :src="'static/images/polling/icon-NFCcode-b.png'" class="img-nfc" />
|
<img :src="'static/images/polling/icon-NFCcode-b.png'" class="img-nfc" />
|
||||||
<view>识别成功</view>
|
<view>识别成功</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="r-right" v-else>
|
||||||
|
<img :src="'static/images/polling/icon-NFCcode.png'" class="img-nfc" /> 开始识别
|
||||||
|
</view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
@@ -127,10 +130,13 @@
|
|||||||
</view>
|
</view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<!-- #ifndef APP-PLUS -->
|
<!-- #ifndef APP-PLUS -->
|
||||||
<view class="r-right r-active">
|
<view class="r-right r-active" v-if="item.resultContent">
|
||||||
<img :src="'static/images/polling/icon-QRcode-b.png'" class="img-nfc" />
|
<img :src="'static/images/polling/icon-QRcode-b.png'" class="img-nfc" />
|
||||||
<view>扫码成功</view>
|
<view>扫码成功</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="r-right" v-else>
|
||||||
|
<img :src="'static/images/polling/icon-QRcode.png'" class="img-nfc" /> 开始扫码
|
||||||
|
</view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
@@ -244,12 +250,11 @@
|
|||||||
|
|
||||||
|
|
||||||
<!-- NFC 数据读取 -->
|
<!-- NFC 数据读取 -->
|
||||||
<NFCTemplate
|
<NFCTemplate v-if="nfcShow" ref="nfcReaderRef"
|
||||||
v-if="nfcShow"
|
:nfcId="nfcId"
|
||||||
ref="nfcReaderRef"
|
@changeNfc="handleNfcData"
|
||||||
@changeNfc="handleNfcData"
|
|
||||||
@close="nfcClose"
|
@close="nfcClose"
|
||||||
/>
|
></NFCTemplate>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -400,7 +405,7 @@ const chooseImage = (item,index) => {
|
|||||||
uni.chooseImage({
|
uni.chooseImage({
|
||||||
// count: 1, // 默认是9,这里设置为1次只选1张
|
// count: 1, // 默认是9,这里设置为1次只选1张
|
||||||
// sizeType: ['compressed'], // 可以指定是原图还是压缩图,可选 'original' 或 'compressed'
|
// sizeType: ['compressed'], // 可以指定是原图还是压缩图,可选 'original' 或 'compressed'
|
||||||
sourceType: ['album', 'camera'], // 指定来源是相册还是相机,默认二者都有
|
sourceType: ['camera'], // 指定来源是相册还是相机,默认二者都有//'album',
|
||||||
// quality:80,
|
// quality:80,
|
||||||
// width:'1920px',
|
// width:'1920px',
|
||||||
// height:'1920px',
|
// height:'1920px',
|
||||||
@@ -455,7 +460,7 @@ const chooseImage = (item,index) => {
|
|||||||
// 视频处理
|
// 视频处理
|
||||||
const chooseVideo = (item,index) => {
|
const chooseVideo = (item,index) => {
|
||||||
uni.chooseVideo({
|
uni.chooseVideo({
|
||||||
sourceType: ['album', 'camera'], // 来源:相册和相机
|
sourceType: ['camera'], // 来源:相册和相机//'album',
|
||||||
maxDuration: 60, // 最大时长(秒)
|
maxDuration: 60, // 最大时长(秒)
|
||||||
camera: 'back', // 使用后置摄像头
|
camera: 'back', // 使用后置摄像头
|
||||||
compressed: true, // 压缩视频
|
compressed: true, // 压缩视频
|
||||||
@@ -537,7 +542,10 @@ let nfcShow = ref(false);
|
|||||||
const nfcReaderRef = ref(null);
|
const nfcReaderRef = ref(null);
|
||||||
// optionObj.pointList
|
// optionObj.pointList
|
||||||
let nfcIndex = ref(0);
|
let nfcIndex = ref(0);
|
||||||
|
let nfcId = ref()
|
||||||
const initNFC = async(item,index) => {
|
const initNFC = async(item,index) => {
|
||||||
|
// console.log("item=>",item)
|
||||||
|
nfcId.value = item.refId;
|
||||||
nfcShow.value = true;
|
nfcShow.value = true;
|
||||||
nfcIndex.value=index;
|
nfcIndex.value=index;
|
||||||
// uni.navigateTo({url:'/pages/business/polling/nfcTest/index'})
|
// uni.navigateTo({url:'/pages/business/polling/nfcTest/index'})
|
||||||
@@ -553,12 +561,9 @@ const nfcClose = async(item) => {
|
|||||||
nfcShow.value = false;
|
nfcShow.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleNfcData=(data)=>{
|
const handleNfcData= async(data)=>{
|
||||||
console.log("NFC数据:", data);
|
console.log("NFC数据:", data);
|
||||||
// console.log("NFC数据1111:", optionObj.value.pointList,nfcIndex.value)
|
|
||||||
optionObj.value.pointList[nfcIndex.value].resultContent = data;
|
optionObj.value.pointList[nfcIndex.value].resultContent = data;
|
||||||
// console.log("NFC数据1111:", optionObj.value.pointList[nfcIndex.value])
|
|
||||||
// nfcShow.value = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 扫二维码
|
// 扫二维码
|
||||||
|
|||||||
501
src/pages/business/polling/problemInitiative.vue
Normal file
501
src/pages/business/polling/problemInitiative.vue
Normal file
@@ -0,0 +1,501 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" title="新增问题上报"
|
||||||
|
:leftFlag="true" :rightFlag="false"
|
||||||
|
></customHeader>
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 下拉刷新 -->
|
||||||
|
<mescroll-uni ref="mescrollRef" @init="mescrollInit"
|
||||||
|
:down="downOption" @down="downCallback"
|
||||||
|
:fixed="false" class="scroll-h"
|
||||||
|
>
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="red-title">
|
||||||
|
问题名称
|
||||||
|
<view class="report-list">
|
||||||
|
<input class="r-input uni-input" v-model="optionObj.bugName" placeholder="请输入问题" placeholder-class="place-input" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="report-border"></view>
|
||||||
|
<view class="report-list">
|
||||||
|
<view class="report-pro">提交人</view>
|
||||||
|
<view class="report-right">{{optionObj.createUserName?optionObj.createUserName:realname}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="report-border"></view>
|
||||||
|
<view class="report-list" style="display:block;">
|
||||||
|
问题描述
|
||||||
|
<textarea class="r-input textarea" v-model="optionObj.bugDesc" auto-height
|
||||||
|
placeholder="请输入问题项描述" placeholder-class="place-input"
|
||||||
|
></textarea>
|
||||||
|
</view>
|
||||||
|
<view class="report-border"></view>
|
||||||
|
<view class="report-list" style="display:block;">
|
||||||
|
<view class="r-title">问题点位照片或视频 <text>*</text></view>
|
||||||
|
<view class="img-flex">
|
||||||
|
<view class="img-show" v-for="(item2,index2) in imgArr" :key="index2" @click="showMediaPreview(item2)">
|
||||||
|
<view class="img-delete" @click.stop="handleDelete(imgArr,index2)">
|
||||||
|
<uni-icons type="closeempty" size="16" color="#fff"></uni-icons>
|
||||||
|
</view>
|
||||||
|
<!-- <img :src="item2.shortUrl" /> -->
|
||||||
|
<image :src="item2.shortUrl" mode="aspectFill" />
|
||||||
|
</view>
|
||||||
|
<view class="img-show" v-for="(item2,index2) in videoArr" :key="index2" @click="showMediaPreview(item2)">
|
||||||
|
<view class="img-delete" @click.stop="handleDelete(videoArr,index2)">
|
||||||
|
<uni-icons type="closeempty" size="16" color="#fff"></uni-icons>
|
||||||
|
</view>
|
||||||
|
<view class="img-icon">
|
||||||
|
<img :src="'static/images/polling/icon-play.png'" />
|
||||||
|
</view>
|
||||||
|
<!-- <video :src="item.url" controls></video> -->
|
||||||
|
<DomVideoPlayer :src="item2.url" objectFit="cover" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- loading -->
|
||||||
|
<view class="img-con" v-if="imgLoading">
|
||||||
|
<view class="upload-loading">
|
||||||
|
<uni-icons type="refreshempty" size="30" color="#C9C9C9"></uni-icons>
|
||||||
|
<view>上传中....</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="img-con" @click="chooseMedia" v-else>
|
||||||
|
<img :src="'static/images/polling/icon-AddPorV.png'" class="img-pic" />
|
||||||
|
</view>
|
||||||
|
<!-- #ifdef APP-PLUS -->
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef APP-PLUS -->
|
||||||
|
<!-- <view class="img-con">
|
||||||
|
<img :src="'static/images/polling/icon-AddPorV.png'" class="img-pic" />
|
||||||
|
</view> -->
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="btn-submit">
|
||||||
|
<button type="primary" @click="handleSubmit">提交</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</mescroll-uni>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 图片放大 -->
|
||||||
|
<mediaPreview :visible="isVisible" :url="mediaUrl" @close="handlePreviewClose"></mediaPreview>
|
||||||
|
|
||||||
|
<!-- 选择图片或者视频 -->
|
||||||
|
<chooseMediaVue ref="chooseMediaRef" @getMediaArr="getMediaArr" @closeMedia="closeMedia"></chooseMediaVue>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref,onMounted,onUnmounted,nextTick,computed,reactive, watch,getCurrentInstance } from 'vue'
|
||||||
|
import { onLoad,onShow,onHide} from '@dcloudio/uni-app';
|
||||||
|
import customHeader from '@/components/customHeader.vue';
|
||||||
|
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||||
|
import chooseMediaVue from '@/components/chooseMedia.vue'
|
||||||
|
import mediaPreview from "@/components/mediaPreview.vue"
|
||||||
|
import DomVideoPlayer from 'uniapp-video-player'
|
||||||
|
import { getUserInfo } from '@/api/auth.js'
|
||||||
|
import { patrolBugDetail,patrolBugAdd,patrolBugEdit,minioUpload } from '@/api/polling.js'
|
||||||
|
import {compressImageUni,getFileType} from '@/utils/common.js'
|
||||||
|
import {showAlert,showLoading,hideLoading} from '@/utils/message.js'
|
||||||
|
import { MINIO_KEY } from '@/enums/cacheEnums';
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
let bugId = ref('');//问题id
|
||||||
|
let realname = ref('');
|
||||||
|
let desc = ref('');//描述
|
||||||
|
let minioObj = {};
|
||||||
|
onLoad(async option => {
|
||||||
|
// console.log(option)
|
||||||
|
bugId.value = option.bugId;
|
||||||
|
minioObj = JSON.parse(uni.getStorageSync(MINIO_KEY) || "\{\}")
|
||||||
|
let userinfo = await getUserInfo({});
|
||||||
|
realname.value = userinfo.realname;
|
||||||
|
|
||||||
|
if(bugId.value)
|
||||||
|
getList();
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(()=>{
|
||||||
|
imgLoading.value=false;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 查询列表
|
||||||
|
let list = ref([]);
|
||||||
|
let optionObj = ref({})
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const mescrollRef = ref(null);
|
||||||
|
const mescrollInit = (mescroll) => {
|
||||||
|
mescrollRef.value = mescroll;
|
||||||
|
};
|
||||||
|
const downOption = ref({
|
||||||
|
use:false,
|
||||||
|
auto: true,
|
||||||
|
textInOffset: '下拉刷新',
|
||||||
|
textOutOffset: '释放更新',
|
||||||
|
textLoading: '刷新中...'
|
||||||
|
});
|
||||||
|
// 下拉刷新
|
||||||
|
const downCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
getList();
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
} finally {
|
||||||
|
mescroll.endSuccess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数据列表
|
||||||
|
const getList = async () => {
|
||||||
|
let param = {
|
||||||
|
bugId:bugId.value
|
||||||
|
}
|
||||||
|
let res = await patrolBugDetail(param);
|
||||||
|
let data = res||{};
|
||||||
|
|
||||||
|
// 视频回显
|
||||||
|
imgArr.value = [];
|
||||||
|
mediaArr.value=[];
|
||||||
|
videoArr.value=[];
|
||||||
|
let fileList =data.bugVedio?.split(",") || [];
|
||||||
|
fileList.forEach(item=>{
|
||||||
|
mediaArr.value.push(item)
|
||||||
|
if(getFileType(item)=='image'){
|
||||||
|
imgArr.value.push({
|
||||||
|
shortUrl:minioObj.minioThumbUrl +"/"+item,
|
||||||
|
url:minioObj.minioUrl +"/"+item,
|
||||||
|
name:item
|
||||||
|
})
|
||||||
|
}else if(getFileType(item)=='video'){
|
||||||
|
videoArr.value.push({
|
||||||
|
shortUrl:minioObj.minioThumbUrl +"/"+item,
|
||||||
|
url:minioObj.minioUrl +"/"+item,
|
||||||
|
name:item
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
optionObj.value = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图片或视频
|
||||||
|
let mediaArr = ref([]);//传给后台的地址
|
||||||
|
let imgArr=ref([]);//图片 后台返回的
|
||||||
|
let videoArr = ref([]);//视频 后台返回的
|
||||||
|
let imgLoading = ref(false)
|
||||||
|
const chooseMedia = () => {
|
||||||
|
proxy.$refs["chooseMediaRef"].openPicker();
|
||||||
|
imgLoading.value=true;
|
||||||
|
}
|
||||||
|
const closeMedia = ()=>{
|
||||||
|
imgLoading.value=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插件回调
|
||||||
|
const getMediaArr=(arr)=>{
|
||||||
|
// console.log("插件回调=>",arr)
|
||||||
|
try {
|
||||||
|
arr.forEach(data=>{
|
||||||
|
mediaArr.value.push(data.fileName);
|
||||||
|
if(data.fileType=="image"){
|
||||||
|
imgArr.value.push({
|
||||||
|
shortUrl:minioObj.minioThumbUrl +"/"+data.fileName,
|
||||||
|
url:minioObj.minioUrl +"/"+data.fileName,
|
||||||
|
name:data.fileName
|
||||||
|
})
|
||||||
|
}else if(data.fileType == "video"){
|
||||||
|
videoArr.value.push({
|
||||||
|
shortUrl:minioObj.minioThumbUrl +"/"+data.fileName,
|
||||||
|
url:minioObj.minioUrl +"/"+data.fileName,
|
||||||
|
name:data.fileName
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// console.log(imgArr.value,videoArr.value)
|
||||||
|
imgLoading.value=false;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
imgLoading.value=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 视频或图片删除 根据数组下标删除数组里的某个图片或视频
|
||||||
|
const handleDelete=(arr,index2)=>{
|
||||||
|
let item = arr[index2];
|
||||||
|
arr.splice(index2, 1);
|
||||||
|
mediaArr.value = mediaArr.value.filter(item2=>item2!=item.name);
|
||||||
|
console.log("删除后=>",mediaArr.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 放大视频或图片
|
||||||
|
let isVisible= ref(false);//放大处理
|
||||||
|
let mediaUrl= ref('');//放大地址
|
||||||
|
let videoShow = ref(true);
|
||||||
|
const showMediaPreview=(item)=>{
|
||||||
|
// console.log("调用放大视频==>",item)
|
||||||
|
isVisible.value = true;
|
||||||
|
videoShow.value = false;
|
||||||
|
mediaUrl.value = item.url
|
||||||
|
}
|
||||||
|
const handlePreviewClose=()=>{
|
||||||
|
isVisible.value = false;
|
||||||
|
videoShow.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交
|
||||||
|
const handleSubmit=()=>{
|
||||||
|
|
||||||
|
showLoading("加载中...")
|
||||||
|
if(bugId.value){
|
||||||
|
let param = {
|
||||||
|
bugId:bugId.value,
|
||||||
|
bugName:optionObj.value.bugName,
|
||||||
|
bugVedio:mediaArr.value.join(","),
|
||||||
|
bugDesc:optionObj.value.bugDesc
|
||||||
|
}
|
||||||
|
// console.log("patrolBugEdit=>",param)
|
||||||
|
patrolBugEdit(param).then(res=>{
|
||||||
|
// showAlert = (content, title = '提示',showCancel=false,succFun)
|
||||||
|
showAlert("修改问题上报成功!","提示",false,()=>{
|
||||||
|
uni.navigateBack()
|
||||||
|
})
|
||||||
|
}).finally(()=>{
|
||||||
|
hideLoading();
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
let param = {
|
||||||
|
bugName:optionObj.value.bugName,
|
||||||
|
bugVedio:mediaArr.value.join(","),
|
||||||
|
bugDesc:optionObj.value.bugDesc
|
||||||
|
}
|
||||||
|
// console.log("patrolBugAdd=>",param)
|
||||||
|
patrolBugAdd(param).then(res=>{
|
||||||
|
showAlert("新建问题上报成功!","提示",false,()=>{
|
||||||
|
bugId.value = res;
|
||||||
|
uni.navigateBack()
|
||||||
|
})
|
||||||
|
}).finally(()=>{
|
||||||
|
hideLoading();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.scroll-h{
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height:calc(100vh - 78px) !important;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 58px) !important;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
:deep(.mescroll-upwarp){
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.white-bg{
|
||||||
|
width: 680rpx;
|
||||||
|
padding: 15rpx 30rpx 40rpx 40rpx;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .red-title{
|
||||||
|
margin-bottom:30rpx;
|
||||||
|
color:#FF2B44;
|
||||||
|
font-size:38rpx;
|
||||||
|
}
|
||||||
|
.white-bg .red-title .uni-input{
|
||||||
|
color:#333;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-border{
|
||||||
|
border-bottom:1px solid #E7E7E7;
|
||||||
|
width:710rpx;
|
||||||
|
height: 1px;
|
||||||
|
margin:30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list{
|
||||||
|
display: flex;
|
||||||
|
font-size:28rpx;
|
||||||
|
}
|
||||||
|
.report-list .r-title{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.report-list text{
|
||||||
|
color:#FF2B44;
|
||||||
|
font-size:28rpx;
|
||||||
|
}
|
||||||
|
.report-list .report-pro{
|
||||||
|
font-size:28rpx;
|
||||||
|
width:16%;
|
||||||
|
/* margin-right:30rpx; */
|
||||||
|
}
|
||||||
|
.report-list .report-right{
|
||||||
|
width:84%;
|
||||||
|
color:#919191;
|
||||||
|
font-size:28rpx;
|
||||||
|
}
|
||||||
|
.report-list .r-input{
|
||||||
|
border:1px solid #E7E7E7;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
width:620rpx;
|
||||||
|
padding:15rpx 25rpx;
|
||||||
|
margin:20rpx 0 0rpx;
|
||||||
|
}
|
||||||
|
.report-list .place-input{
|
||||||
|
color:#BFBFBF;
|
||||||
|
font-size:28rpx;
|
||||||
|
}
|
||||||
|
.report-list .textarea{
|
||||||
|
min-height: 120rpx;
|
||||||
|
}
|
||||||
|
.report-list .r-list{
|
||||||
|
padding: 10rpx 0;
|
||||||
|
}
|
||||||
|
.report-list .r-list:first-child{
|
||||||
|
padding-top:0;
|
||||||
|
}
|
||||||
|
.report-list .r-left{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width:90%;
|
||||||
|
font-size:28rpx;
|
||||||
|
color:#919191;
|
||||||
|
}
|
||||||
|
.report-list .r-left view:first-child{
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
.report-list .r-left.r-red{
|
||||||
|
color: #FF2B44;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .r-right{
|
||||||
|
display: flex;
|
||||||
|
font-size:30rpx;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.report-list .r-r-round{
|
||||||
|
width:35rpx;
|
||||||
|
height:35rpx;
|
||||||
|
border:1px solid #BDBDBD;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.report-list .r-r-round.active{
|
||||||
|
border:1px solid #FF2B44;
|
||||||
|
background-color: #FF2B44;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.report-list .r-r-round.active::after{
|
||||||
|
content:"!";
|
||||||
|
position: absolute;
|
||||||
|
top:0;
|
||||||
|
left:0;
|
||||||
|
color:#fff;
|
||||||
|
text-align: center;
|
||||||
|
width:35rpx;
|
||||||
|
height:35rpx;
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
line-height: 30rpx;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height:33rpx;
|
||||||
|
padding-top:2rpx;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
.report-list .img-flex{
|
||||||
|
display: flex;
|
||||||
|
flex-flow:row wrap;
|
||||||
|
margin-bottom:30rpx;
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
.report-list .img-show img,
|
||||||
|
.report-list .img-show image,
|
||||||
|
.report-list .img-show video,
|
||||||
|
.report-list .img-show .player-wrapper{
|
||||||
|
width:210rpx;
|
||||||
|
height: 140rpx;
|
||||||
|
}
|
||||||
|
.report-list .img-show :deep(.uni-video-cover-play-button){
|
||||||
|
width:64rpx;
|
||||||
|
height: 64rpx;
|
||||||
|
line-height: 64rpx;
|
||||||
|
font-size:60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .img-con{
|
||||||
|
background-color: #EEEEEE;
|
||||||
|
width:210rpx;
|
||||||
|
height: 140rpx;
|
||||||
|
text-align: center;
|
||||||
|
color:#919191;
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
.report-list .img-con .img-pic{
|
||||||
|
width:76rpx;
|
||||||
|
height: 76rpx;
|
||||||
|
margin-top:30rpx;
|
||||||
|
}
|
||||||
|
.report-list .img-show,
|
||||||
|
.report-list .img-con{
|
||||||
|
width: calc(100% / 3 - 10px); /* 减去一些间隙以避免溢出 */
|
||||||
|
margin:20rpx 20rpx 0 0;
|
||||||
|
}
|
||||||
|
.report-list .img-show{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.report-list .img-show .img-delete{
|
||||||
|
position: absolute;
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
right:4rpx;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
right:4rpx;
|
||||||
|
/* #endif */
|
||||||
|
top:8rpx;
|
||||||
|
width:34rpx;
|
||||||
|
height:34rpx;
|
||||||
|
line-height:34rpx;
|
||||||
|
border-radius:3rpx;
|
||||||
|
background-color: rgba(0, 0, 0, 0.6);
|
||||||
|
text-align: center;
|
||||||
|
z-index:1;
|
||||||
|
}
|
||||||
|
.report-list .img-show .img-icon{
|
||||||
|
position: absolute;
|
||||||
|
top:50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 64rpx;
|
||||||
|
height:64rpx;
|
||||||
|
margin-left:-32rpx;
|
||||||
|
margin-top:-32rpx;
|
||||||
|
z-index:1;
|
||||||
|
}
|
||||||
|
.report-list .img-show .img-icon img{
|
||||||
|
width: 64rpx;
|
||||||
|
height:64rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.btn-submit{
|
||||||
|
width:400rpx;
|
||||||
|
margin:90rpx auto;
|
||||||
|
}
|
||||||
|
.btn-submit uni-button[type='primary']{
|
||||||
|
background-color: #05A3F4;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
line-height: 2.2;
|
||||||
|
}
|
||||||
|
.btn-submit uni-button:after{
|
||||||
|
border-color:#05A3F4;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
402
src/pages/business/polling/problemInitiativeDetail.vue
Normal file
402
src/pages/business/polling/problemInitiativeDetail.vue
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" title="问题上报"
|
||||||
|
:leftFlag="true" :rightFlag="true"
|
||||||
|
>
|
||||||
|
<template #right>
|
||||||
|
<view class="head-right" @click="handleQuestion" v-if="problemObj.bugStatus==1">
|
||||||
|
<view class="btn-yellow">
|
||||||
|
<uni-icons type="plus" size="20" color="#4C2D11"></uni-icons> 新增跟踪信息
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</customHeader>
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 下拉刷新 -->
|
||||||
|
<mescroll-uni ref="mescrollRef" @init="mescrollInit"
|
||||||
|
:down="downOption" @down="downCallback"
|
||||||
|
:fixed="false" class="scroll-h"
|
||||||
|
>
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="red-title">问题:{{problemObj.bugName}}</view>
|
||||||
|
<view class="report-border"></view>
|
||||||
|
<view class="report-list">
|
||||||
|
<view style="width:45%;display:flex;">
|
||||||
|
<view class="report-pro report-w" style="margin-right:20rpx;">提交人</view>
|
||||||
|
<view class="report-right report-w">{{problemObj.createUserName}}</view>
|
||||||
|
</view>
|
||||||
|
<view style="width:55%;display:flex;">
|
||||||
|
<view class="report-pro report-w" style="margin-right:20rpx;">提交时间</view>
|
||||||
|
<view class="report-right report-w">{{parseTime(problemObj.createTime,'{y}-{m}-{d} {h}:{i}')}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="report-border"></view>
|
||||||
|
<view class="report-list">问题描述</view>
|
||||||
|
<view class="report-list report-gray">{{problemObj.bugDesc}}</view>
|
||||||
|
<view class="report-border"></view>
|
||||||
|
<view class="report-list">问题点位照片或视频</view>
|
||||||
|
<view class="report-list">
|
||||||
|
<view class="img-flex">
|
||||||
|
<block v-for="(item2,index2) in problemObj.listFile" :key="index2">
|
||||||
|
<view class="img-show" v-if="getFileType(item2)=='image'" @click="showMediaPreview(item2)">
|
||||||
|
<image :src="minioObj.minioThumbUrl+'/'+item2" mode="aspectFill" />
|
||||||
|
</view>
|
||||||
|
<view class="img-show" v-else-if="getFileType(item2)=='video'" @click="showMediaPreview(item2)">
|
||||||
|
<view class="img-icon">
|
||||||
|
<img :src="'static/images/polling/icon-play.png'" />
|
||||||
|
</view>
|
||||||
|
<!-- <video :src="minioObj.minioUrl+'/'+item" controls v-show="videoShow"></video> -->
|
||||||
|
<DomVideoPlayer :src="minioObj.minioUrl+'/'+item2" objectFit="cover" v-show="videoShow" />
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 当天提的 增加按钮 修改和删除 -->
|
||||||
|
<view class="btn-con" v-if="isToday && problemObj.bugStatus==1">
|
||||||
|
<button type="primary" @click="handleUpdate" size="mini" style="margin-right:50rpx;" class="btn-primary">修改</button>
|
||||||
|
<button type="primary" @click="handleDelete" size="mini">删除</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 追踪列表 -->
|
||||||
|
<block v-if="problemObj.logList">
|
||||||
|
<block v-if="problemObj.logList.length>0">
|
||||||
|
<view class="bg-border"></view>
|
||||||
|
<view v-for="(item,index) in problemObj.logList" :key="index" class="log-con">
|
||||||
|
<view class="blue-title">
|
||||||
|
{{parseTime(item.createTime,'{y}-{m}-{d} {h}:{i}')}}
|
||||||
|
<text style="margin-left:20rpx;">巡检人:{{item.modifyUserName}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="report-list">检查点跟踪情况描述</view>
|
||||||
|
<view class="report-list report-gray">{{item.logDesc}}</view>
|
||||||
|
<view class="report-border"></view>
|
||||||
|
<view class="report-list">检查点位照片或视频</view>
|
||||||
|
<view class="report-list">
|
||||||
|
<view class="img-flex">
|
||||||
|
<block v-for="(item2,index2) in item.listFile" :key="index2">
|
||||||
|
<view class="img-show" v-if="getFileType(item2)=='image'" @click="showMediaPreview(item2)">
|
||||||
|
<image :src="minioObj.minioThumbUrl+'/'+item2" mode="aspectFill" />
|
||||||
|
</view>
|
||||||
|
<view class="img-show" v-else-if="getFileType(item2)=='video'" @click="showMediaPreview(item2)">
|
||||||
|
<view class="img-icon">
|
||||||
|
<img :src="'static/images/polling/icon-play.png'" />
|
||||||
|
</view>
|
||||||
|
<!-- <video :src="minioObj.minioUrl+'/'+item" controls v-show="videoShow"></video> -->
|
||||||
|
<DomVideoPlayer :src="minioObj.minioUrl+'/'+item2" objectFit="cover" v-show="videoShow" />
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
</mescroll-uni>
|
||||||
|
</view>
|
||||||
|
<!-- 图片放大 -->
|
||||||
|
<mediaPreview :visible="isVisible" :url="mediaUrl" @close="handlePreviewClose"></mediaPreview>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref,onMounted,onUnmounted,nextTick,computed,reactive } from 'vue'
|
||||||
|
import { onLoad,onShow,onHide} from '@dcloudio/uni-app';
|
||||||
|
import customHeader from '@/components/customHeader.vue';
|
||||||
|
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||||
|
import mediaPreview from "@/components/mediaPreview.vue"
|
||||||
|
import DomVideoPlayer from 'uniapp-video-player'
|
||||||
|
import { parseTime } from '@/utils/datetime.js';
|
||||||
|
import {getFileType} from '@/utils/common.js';
|
||||||
|
import { patrolBugDetail,patrolBugDel } from '@/api/polling.js'
|
||||||
|
import { MINIO_KEY } from '@/enums/cacheEnums';
|
||||||
|
import {showAlert,showLoading,hideLoading} from '@/utils/message.js'
|
||||||
|
|
||||||
|
let bugId=ref('');
|
||||||
|
let problemObj = ref({});
|
||||||
|
let isToday = ref(false);
|
||||||
|
let minioObj = {};
|
||||||
|
onLoad(option => {
|
||||||
|
// console.log(option)
|
||||||
|
bugId.value = option.bugId;
|
||||||
|
minioObj = JSON.parse(uni.getStorageSync(MINIO_KEY) || "\{\}")
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(()=>{
|
||||||
|
getList();
|
||||||
|
})
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const mescrollRef = ref(null);
|
||||||
|
const mescrollInit = (mescroll) => {
|
||||||
|
mescrollRef.value = mescroll;
|
||||||
|
};
|
||||||
|
const downOption = ref({
|
||||||
|
auto: false,
|
||||||
|
textInOffset: '下拉刷新',
|
||||||
|
textOutOffset: '释放更新',
|
||||||
|
textLoading: '刷新中...'
|
||||||
|
});
|
||||||
|
// 下拉刷新
|
||||||
|
const downCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
getList();
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
} finally {
|
||||||
|
mescroll.endSuccess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 获取数据列表
|
||||||
|
const getList = async() => {
|
||||||
|
isToday.value = false;
|
||||||
|
let data = await patrolBugDetail({bugId:bugId.value});
|
||||||
|
// data.list = data.pointName?.split(",") || [];
|
||||||
|
data.listFile=data.bugVedio?.split(",") || [];
|
||||||
|
data.logList.forEach(item => {
|
||||||
|
item.listFile = item.logVedio?.split(",")||[]
|
||||||
|
});
|
||||||
|
// 判断是否当天创建的,显示按钮
|
||||||
|
let createTime = parseTime(data.createTime,'{y}-{m}-{d}');
|
||||||
|
let dateNow = parseTime(new Date().getTime(),'{y}-{m}-{d}');
|
||||||
|
if(createTime == dateNow){
|
||||||
|
isToday.value = true;
|
||||||
|
}
|
||||||
|
problemObj.value = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 放大视频或图片
|
||||||
|
let isVisible= ref(false);//放大处理
|
||||||
|
let mediaUrl= ref('');//放大地址
|
||||||
|
let videoShow = ref(true);
|
||||||
|
const showMediaPreview=(url)=>{
|
||||||
|
url = minioObj.minioUrl+'/'+url;
|
||||||
|
isVisible.value = true;
|
||||||
|
videoShow.value = false;
|
||||||
|
mediaUrl.value = url;
|
||||||
|
}
|
||||||
|
const handlePreviewClose=()=>{
|
||||||
|
isVisible.value = false;
|
||||||
|
videoShow.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转问题上报页面
|
||||||
|
const handleQuestion=()=>{
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/business/polling/problemInitiativeLog?bugId='+bugId.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改
|
||||||
|
const handleUpdate=()=>{
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/business/polling/problemInitiative?bugId='+bugId.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
const handleDelete=()=>{
|
||||||
|
showLoading("加载中...")
|
||||||
|
patrolBugDel({bugId:bugId.value}).then(res=>{
|
||||||
|
// content, title = '提示',showCancel=false,succFun
|
||||||
|
showAlert("删除成功!",'提示',false,()=>{
|
||||||
|
uni.navigateBack()
|
||||||
|
})
|
||||||
|
}).finally(()=>{
|
||||||
|
hideLoading();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.scroll-h{
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height:calc(100vh - 78px) !important;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 58px) !important;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
:deep(.mescroll-upwarp){
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.head-right{}
|
||||||
|
.head-right .btn-yellow{
|
||||||
|
background-color: #FCC123;
|
||||||
|
color: #4C2D11;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
padding:10rpx 25rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.head-right .btn-yellow .img-repair{
|
||||||
|
width: 30rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
}
|
||||||
|
.white-bg{
|
||||||
|
width: 680rpx;
|
||||||
|
padding: 15rpx 30rpx 50rpx 40rpx;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .red-title{
|
||||||
|
margin-bottom:30rpx;
|
||||||
|
color:#FF2B44;
|
||||||
|
font-size:38rpx;
|
||||||
|
}
|
||||||
|
.report-border{
|
||||||
|
border-bottom:1px solid #E7E7E7;
|
||||||
|
width:710rpx;
|
||||||
|
height: 1px;
|
||||||
|
margin:30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list{
|
||||||
|
display: flex;
|
||||||
|
font-size:28rpx;
|
||||||
|
}
|
||||||
|
.report-list.report-gray{
|
||||||
|
color:#919191;
|
||||||
|
padding:20rpx 0 0;
|
||||||
|
}
|
||||||
|
.report-list .r-title{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.report-list text{
|
||||||
|
color:#FF2B44;
|
||||||
|
font-size:28rpx;
|
||||||
|
}
|
||||||
|
.report-list .report-pro{
|
||||||
|
font-size:28rpx;
|
||||||
|
width:16%;
|
||||||
|
/* margin-right:30rpx; */
|
||||||
|
}
|
||||||
|
.report-list .report-right{
|
||||||
|
width:84%;
|
||||||
|
color:#919191;
|
||||||
|
font-size:28rpx;
|
||||||
|
}
|
||||||
|
.report-list .report-w{
|
||||||
|
width:auto;
|
||||||
|
}
|
||||||
|
.report-list .r-list{
|
||||||
|
padding: 10rpx 0;
|
||||||
|
}
|
||||||
|
.report-list .r-list:first-child{
|
||||||
|
padding-top:0;
|
||||||
|
}
|
||||||
|
.report-list .r-left{
|
||||||
|
display: flex;
|
||||||
|
/* align-items: center; */
|
||||||
|
font-size:28rpx;
|
||||||
|
color:#919191;
|
||||||
|
}
|
||||||
|
.report-list .r-left view:first-child{
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
.report-list .r-left.r-red{
|
||||||
|
color: #FF2B44;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .r-right{
|
||||||
|
display: flex;
|
||||||
|
font-size:30rpx;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.report-list .img-flex{
|
||||||
|
display: flex;
|
||||||
|
flex-flow:row wrap;
|
||||||
|
margin-bottom:30rpx;
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
.report-list .img-con{
|
||||||
|
background-color: #EEEEEE;
|
||||||
|
width:210rpx;
|
||||||
|
height: 140rpx;
|
||||||
|
text-align: center;
|
||||||
|
color:#919191;
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
.report-list .img-con .img-pic{
|
||||||
|
width:76rpx;
|
||||||
|
height: 76rpx;
|
||||||
|
margin-top:30rpx;
|
||||||
|
}
|
||||||
|
.report-list .img-show,
|
||||||
|
.report-list .img-con{
|
||||||
|
width: calc(100% / 3 - 10px); /* 减去一些间隙以避免溢出 */
|
||||||
|
margin:20rpx 20rpx 0 0;
|
||||||
|
}
|
||||||
|
.report-list .img-show{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.report-list .img-show .img-icon{
|
||||||
|
position: absolute;
|
||||||
|
top:50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 64rpx;
|
||||||
|
height:64rpx;
|
||||||
|
margin-left:-32rpx;
|
||||||
|
margin-top:-32rpx;
|
||||||
|
z-index:1;
|
||||||
|
}
|
||||||
|
.report-list .img-show .img-icon img{
|
||||||
|
width: 64rpx;
|
||||||
|
height:64rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .img-show img,
|
||||||
|
.report-list .img-show video,
|
||||||
|
.report-list .img-show image,
|
||||||
|
.report-list .img-show .player-wrapper{
|
||||||
|
width:210rpx;
|
||||||
|
height: 140rpx;
|
||||||
|
}
|
||||||
|
.report-list .img-show :deep(.uni-video-cover-play-button){
|
||||||
|
width:64rpx;
|
||||||
|
height: 64rpx;
|
||||||
|
line-height: 64rpx;
|
||||||
|
font-size:60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-con{
|
||||||
|
text-align: center;
|
||||||
|
padding-top:50rpx;
|
||||||
|
}
|
||||||
|
uni-button[type='primary']{
|
||||||
|
background-color: #05A3F4;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
line-height: 2.5;
|
||||||
|
padding:0 80rpx;
|
||||||
|
}
|
||||||
|
uni-button:after{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-border{
|
||||||
|
width:750rpx;
|
||||||
|
height:20rpx;
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
margin-left:-40rpx;
|
||||||
|
margin-top:40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-con{
|
||||||
|
padding-top:10rpx;
|
||||||
|
}
|
||||||
|
.log-con .blue-title{
|
||||||
|
font-size:32rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
334
src/pages/business/polling/problemInitiativeList.vue
Normal file
334
src/pages/business/polling/problemInitiativeList.vue
Normal file
@@ -0,0 +1,334 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" :title="!searchShow?'巡检问题上报':'搜索'"
|
||||||
|
:leftFlag="true"
|
||||||
|
:rightFlag="true"
|
||||||
|
@back="handleBack" :searchType="searchShow?1:undefined"
|
||||||
|
>
|
||||||
|
<template #right>
|
||||||
|
<view class="head-right" @click="handleQuestion">
|
||||||
|
<view class="btn-yellow">
|
||||||
|
<uni-icons type="plus" size="20" color="#4C2D11"></uni-icons> 新建问题上报
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</customHeader>
|
||||||
|
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 搜索处理 -->
|
||||||
|
<customSearch v-if="searchShow"
|
||||||
|
:searchKeywords="searchText"
|
||||||
|
:searchType="searchTypeObj"
|
||||||
|
@confirm="handleSearchConfirm"
|
||||||
|
></customSearch>
|
||||||
|
<view class="search" v-else>
|
||||||
|
<uni-search-bar class="custom-search" radius="28"
|
||||||
|
placeholder="请输入搜索条件"
|
||||||
|
clearButton="auto" cancelButton="none"
|
||||||
|
bgColor="#6FA2F8" textColor="#ffffff"
|
||||||
|
@focus="handleSearchFocus"
|
||||||
|
v-model="searchText"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<mescroll-uni v-if="!searchShow" ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
|
||||||
|
:up="upOption" :down="downOption" :fixed="false" class="scroll-h" :class="{'loading-scroll':cssFlag}">
|
||||||
|
<view class="white-bg" :class="{'bg-height':list.length<8}">
|
||||||
|
<block v-if="list.length>0">
|
||||||
|
<view class="report-list" v-for="(item, index) in list" :key="index" @click="handleDetail(item)">
|
||||||
|
<view class="r-list" style="padding-bottom:0">
|
||||||
|
<view class="r-name">{{ item.bugName }}</view>
|
||||||
|
<view class="r-right">
|
||||||
|
<!-- 问题状态 1=追踪、2=关闭 -->
|
||||||
|
<view v-if="item.bugStatus==1" class="btn-red">进行中</view>
|
||||||
|
<view v-if="item.bugStatus==2" class="btn-green">已解决</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="r-list">
|
||||||
|
<view class="r-left">
|
||||||
|
<view class="r-l-left" style="width:220rpx">跟踪次数<span class="r-gray">{{ item.logNum }}</span></view>
|
||||||
|
<view class="r-l-right">最近跟踪时间<span class="r-gray">{{parseTime(item.lastLogTime,'{y}-{m}-{d} {h}:{i}') }}</span></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="report-border" v-if="index<list.length-1"></view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<view v-else class="no-data">
|
||||||
|
<img :src="'static/images/polling/pic-NoResult.png'" class="no-pic" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</mescroll-uni>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted,computed } from 'vue'
|
||||||
|
import { onLoad,onHide, onShow } from '@dcloudio/uni-app';
|
||||||
|
import customHeader from '@/components/customHeader.vue'
|
||||||
|
import customSearch from '@/components/customSearch.vue'
|
||||||
|
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||||
|
import { getNavBarPaddingTop } from '@/utils/system.js'
|
||||||
|
import { parseTime } from '@/utils/datetime.js'
|
||||||
|
import { patrolBugList } from '@/api/polling.js'
|
||||||
|
|
||||||
|
onLoad(async(opt) => {
|
||||||
|
uni.setStorageSync('page_cache',true);
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(()=>{
|
||||||
|
triggerRefresh();
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取导航栏高度用于内容区域padding
|
||||||
|
const navBarPaddingTop = ref(0);
|
||||||
|
onMounted(() => {
|
||||||
|
navBarPaddingTop.value = getNavBarPaddingTop() * 2;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 搜索处理
|
||||||
|
let searchShow = ref(false);
|
||||||
|
let searchText = ref(undefined);
|
||||||
|
let searchTypeObj = ref({typeId:5});
|
||||||
|
|
||||||
|
onHide(()=>{
|
||||||
|
searchShow.value=false;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 搜索返回操作
|
||||||
|
const handleBack=()=>{
|
||||||
|
searchShow.value=false;
|
||||||
|
}
|
||||||
|
// 获取input 焦点跳转
|
||||||
|
const handleSearchFocus=()=>{
|
||||||
|
searchShow.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索完返回处理
|
||||||
|
const handleSearchConfirm = (param1,param2)=>{
|
||||||
|
// console.log(param1,param2)
|
||||||
|
searchText.value=param2.value;;
|
||||||
|
searchShow.value=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除未读
|
||||||
|
const handleRead = () => {
|
||||||
|
list.value.forEach(item => {
|
||||||
|
item.isRead = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 查询通知列表
|
||||||
|
let list = ref([]);
|
||||||
|
const mescrollRef = ref(null);
|
||||||
|
const upOption = ref({
|
||||||
|
page: { num: 0, size: 10 },
|
||||||
|
noMoreSize: 5,
|
||||||
|
empty: {
|
||||||
|
tip: '~ 空空如也 ~',
|
||||||
|
icon: "../../../static/images/mescroll-empty.png"
|
||||||
|
},
|
||||||
|
textLoading: '加载中...',
|
||||||
|
textNoMore: '已经到底了'
|
||||||
|
});
|
||||||
|
|
||||||
|
const downOption = ref({
|
||||||
|
auto: false,
|
||||||
|
textInOffset: '下拉刷新',
|
||||||
|
textOutOffset: '释放更新',
|
||||||
|
textLoading: '刷新中...'
|
||||||
|
});
|
||||||
|
|
||||||
|
let cssFlag=ref(false);//控制样式
|
||||||
|
const mescrollInit = (mescroll) => {
|
||||||
|
cssFlag.value = true;
|
||||||
|
mescrollRef.value = mescroll;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const downCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
console.log("下拉刷新")
|
||||||
|
const res = await getList(1, upOption.value.page.size);
|
||||||
|
cssFlag.value = false;
|
||||||
|
list.value = res.list;
|
||||||
|
// mescroll.resetUpScroll();
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
} finally {
|
||||||
|
setTimeout(async ()=>{
|
||||||
|
mescroll.endSuccess();
|
||||||
|
},500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 上拉加载更多
|
||||||
|
const upCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
console.log("上拉加载更多")
|
||||||
|
let res = await getList(mescroll.num, mescroll.size);
|
||||||
|
if (mescroll.num === 1) {
|
||||||
|
list.value = res.list;
|
||||||
|
} else {
|
||||||
|
list.value.push(...res.list);
|
||||||
|
}
|
||||||
|
mescroll.endBySize(res.list.length, res.total);
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数据列表
|
||||||
|
const getList = (pageIndex, pageSize) => {
|
||||||
|
return new Promise(async (resolve) => {
|
||||||
|
let param = {
|
||||||
|
pageIndex,
|
||||||
|
pageSize,
|
||||||
|
key:searchText.value?searchText.value:undefined,
|
||||||
|
}
|
||||||
|
let res = await patrolBugList(param);
|
||||||
|
let list = res.list || [];
|
||||||
|
resolve({
|
||||||
|
list,
|
||||||
|
// total: res.recordCount || 0
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 主动触发下拉刷新
|
||||||
|
const triggerRefresh = () => {
|
||||||
|
if (mescrollRef.value) {
|
||||||
|
mescrollRef.value.mescroll.triggerDownScroll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转问题上报页面
|
||||||
|
const handleQuestion=()=>{
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/business/polling/problemInitiative'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看详情
|
||||||
|
const handleDetail = (item) =>{
|
||||||
|
let url= '/pages/business/polling/problemInitiativeDetail?bugId='+item.bugId;
|
||||||
|
uni.navigateTo({
|
||||||
|
url
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.all-body{
|
||||||
|
position: absolute;
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
top:150rpx;
|
||||||
|
height: calc(100vh - 75px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
top:120rpx;
|
||||||
|
height: calc(100vh - 64px);
|
||||||
|
/* #endif */
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.mescroll-downwarp .downwarp-progress){
|
||||||
|
border-color:#fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.mescroll-downwarp .downwarp-tip){
|
||||||
|
color:#fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-right{}
|
||||||
|
.head-right .btn-yellow{
|
||||||
|
background-color: #FCC123;
|
||||||
|
color: #4C2D11;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
padding:10rpx 25rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.head-right .btn-yellow .img-repair{
|
||||||
|
width: 30rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg {
|
||||||
|
width: 670rpx;
|
||||||
|
padding: 30rpx 40rpx 40rpx;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.white-bg.bg-height{
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height: calc(100vh - 150px);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 140px);
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
.scroll-h{
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height: calc(100vh - 123px) !important;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 105px) !important;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.report-border{
|
||||||
|
border-bottom:1px solid #E7E7E7;
|
||||||
|
width:710rpx;
|
||||||
|
height: 1px;
|
||||||
|
margin:20rpx 0;
|
||||||
|
}
|
||||||
|
.report-list .r-list{
|
||||||
|
padding: 5rpx 0;
|
||||||
|
}
|
||||||
|
.report-list .r-list .r-left{
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.report-list .r-list .r-gray{
|
||||||
|
margin-left:10rpx;
|
||||||
|
}
|
||||||
|
.report-list .r-list .r-blue{
|
||||||
|
margin-left:10rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.report-list .r-list .r-red{
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.report-list .r-list .r-name{
|
||||||
|
width:525rpx
|
||||||
|
}
|
||||||
|
.r-left .r-l-left{
|
||||||
|
width:280rpx;
|
||||||
|
}
|
||||||
|
.r-left .r-l-right{
|
||||||
|
|
||||||
|
}
|
||||||
|
.no-data .no-pic{
|
||||||
|
display: block;
|
||||||
|
width:440rpx;
|
||||||
|
height:210rpx;
|
||||||
|
margin:40rpx auto;
|
||||||
|
}
|
||||||
|
:deep(.mescroll-upwarp){
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.mescroll-empty){
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
498
src/pages/business/polling/problemInitiativeLog.vue
Normal file
498
src/pages/business/polling/problemInitiativeLog.vue
Normal file
@@ -0,0 +1,498 @@
|
|||||||
|
<template>
|
||||||
|
<view class="con-body">
|
||||||
|
<view class="con-bg">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<customHeader ref="customHeaderRef" title="新增跟踪信息"
|
||||||
|
:leftFlag="true" :rightFlag="false"
|
||||||
|
></customHeader>
|
||||||
|
<!-- 高度来避免头部遮挡 -->
|
||||||
|
<view class="top-height"></view>
|
||||||
|
|
||||||
|
<!-- 下拉刷新 -->
|
||||||
|
<mescroll-uni ref="mescrollRef" @init="mescrollInit"
|
||||||
|
:down="downOption" @down="downCallback"
|
||||||
|
:fixed="false" class="scroll-h"
|
||||||
|
>
|
||||||
|
<view class="white-bg">
|
||||||
|
<view class="red-title">问题:{{optionObj.bugName}}</view>
|
||||||
|
<view class="report-border"></view>
|
||||||
|
<view class="report-list">
|
||||||
|
<view class="report-pro">提交人</view>
|
||||||
|
<view class="report-right">{{optionObj.createUserName}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="report-border"></view>
|
||||||
|
<view class="report-list" style="display:block;">
|
||||||
|
检查点跟踪情况描述
|
||||||
|
<textarea class="r-input textarea" v-model="desc" auto-height
|
||||||
|
placeholder="请输入跟踪情况描述" placeholder-class="place-input"
|
||||||
|
></textarea>
|
||||||
|
</view>
|
||||||
|
<view class="report-border"></view>
|
||||||
|
<view class="report-list" style="display:block;">
|
||||||
|
<view class="r-title">问题点位照片或视频 <text>*</text></view>
|
||||||
|
<view class="img-flex">
|
||||||
|
<view class="img-show" v-for="(item2,index2) in imgArr" :key="index2" @click="showMediaPreview(item2)">
|
||||||
|
<view class="img-delete" @click.stop="handleDelete(imgArr,index2)">
|
||||||
|
<uni-icons type="closeempty" size="16" color="#fff"></uni-icons>
|
||||||
|
</view>
|
||||||
|
<image :src="item2.shortUrl" mode="aspectFill" />
|
||||||
|
</view>
|
||||||
|
<view class="img-show" v-for="(item2,index2) in videoArr" :key="index2" @click="showMediaPreview(item2)">
|
||||||
|
<view class="img-delete" @click.stop="handleDelete(videoArr,index2)">
|
||||||
|
<uni-icons type="closeempty" size="16" color="#fff"></uni-icons>
|
||||||
|
</view>
|
||||||
|
<view class="img-icon">
|
||||||
|
<img :src="'static/images/polling/icon-play.png'" />
|
||||||
|
</view>
|
||||||
|
<!-- <video :src="item" controls></video> -->
|
||||||
|
<DomVideoPlayer :src="item2.url" objectFit="cover" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- loading -->
|
||||||
|
<view class="img-con" v-if="imgLoading">
|
||||||
|
<view class="upload-loading">
|
||||||
|
<uni-icons type="refreshempty" size="30" color="#C9C9C9"></uni-icons>
|
||||||
|
<view>上传中....</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="img-con" @click="chooseMedia" v-else>
|
||||||
|
<img :src="'static/images/polling/icon-AddPorV.png'" class="img-pic" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- #ifdef APP-PLUS -->
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef APP-PLUS -->
|
||||||
|
<!-- <view class="img-con">
|
||||||
|
<img :src="'static/images/polling/icon-AddPorV.png'" class="img-pic" />
|
||||||
|
</view> -->
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="btn-submit">
|
||||||
|
<button type="primary" @click="handleSubmit">提交</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</mescroll-uni>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 图片放大 -->
|
||||||
|
<mediaPreview :visible="isVisible" :url="mediaUrl" @close="handlePreviewClose"></mediaPreview>
|
||||||
|
|
||||||
|
<!-- 选择图片或者视频 -->
|
||||||
|
<chooseMediaVue ref="chooseMediaRef" @getMediaArr="getMediaArr" @closeMedia="closeMedia"></chooseMediaVue>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref,onMounted,onUnmounted,nextTick,computed,reactive,getCurrentInstance } from 'vue'
|
||||||
|
import { onLoad,onHide, onShow} from '@dcloudio/uni-app';
|
||||||
|
import customHeader from '@/components/customHeader.vue';
|
||||||
|
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
|
||||||
|
import mediaPreview from "@/components/mediaPreview.vue"
|
||||||
|
import chooseMediaVue from '@/components/chooseMedia.vue'
|
||||||
|
import DomVideoPlayer from 'uniapp-video-player'
|
||||||
|
import { getUserInfo } from '@/api/auth.js'
|
||||||
|
import { patrolBugDetail,patrolBugAddLog,minioUpload } from '@/api/polling.js'
|
||||||
|
import { MINIO_KEY } from '@/enums/cacheEnums';
|
||||||
|
import {showAlert,showLoading,hideLoading} from '@/utils/message.js'
|
||||||
|
import {compressImageUni} from '@/utils/common.js'
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
let bugId = ref('');
|
||||||
|
let realname = ref('');
|
||||||
|
let desc = ref('');//描述
|
||||||
|
let minioObj = {};
|
||||||
|
onLoad(async option => {
|
||||||
|
// console.log(option)
|
||||||
|
bugId.value = option.bugId;
|
||||||
|
|
||||||
|
minioObj = JSON.parse(uni.getStorageSync(MINIO_KEY) || "\{\}")
|
||||||
|
let userinfo = await getUserInfo({});
|
||||||
|
realname.value = userinfo.realname
|
||||||
|
|
||||||
|
getList();
|
||||||
|
})
|
||||||
|
onShow(()=>{
|
||||||
|
imgLoading.value=false;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 查询列表
|
||||||
|
let list = ref([]);
|
||||||
|
let optionObj = ref({})
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const mescrollRef = ref(null);
|
||||||
|
const mescrollInit = (mescroll) => {
|
||||||
|
mescrollRef.value = mescroll;
|
||||||
|
};
|
||||||
|
const downOption = ref({
|
||||||
|
use:false,
|
||||||
|
auto: false,
|
||||||
|
textInOffset: '下拉刷新',
|
||||||
|
textOutOffset: '释放更新',
|
||||||
|
textLoading: '刷新中...'
|
||||||
|
});
|
||||||
|
// 下拉刷新
|
||||||
|
const downCallback = async (mescroll) => {
|
||||||
|
try {
|
||||||
|
getList();
|
||||||
|
} catch (error) {
|
||||||
|
mescroll.endErr();
|
||||||
|
} finally {
|
||||||
|
mescroll.endSuccess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数据列表
|
||||||
|
const getList = async () => {
|
||||||
|
let res = await patrolBugDetail({bugId:bugId.value});
|
||||||
|
let data = res || {};
|
||||||
|
// data.list = data.pointName.split(",") || [];
|
||||||
|
optionObj.value = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图片或视频
|
||||||
|
let mediaArr = ref([]);//传给后台的地址
|
||||||
|
let imgArr=ref([]);//图片 后台返回的
|
||||||
|
let videoArr = ref([]);//视频 后台返回的
|
||||||
|
let imgLoading = ref(false)
|
||||||
|
const chooseMedia = () => {
|
||||||
|
proxy.$refs["chooseMediaRef"].openPicker();
|
||||||
|
imgLoading.value=true;
|
||||||
|
/* uni.chooseMedia({
|
||||||
|
count: 9,
|
||||||
|
mediaType: ['image', 'video'], // 指定可选择图片和视频
|
||||||
|
sourceType: ['album', 'camera'],
|
||||||
|
maxDuration: 60, // 拍摄视频最长拍摄时间
|
||||||
|
camera: 'back',
|
||||||
|
success: (res) => {
|
||||||
|
console.log("问题跟踪chooseMedia=>",res)
|
||||||
|
res.tempFiles.forEach(async file => {
|
||||||
|
console.log(`文件类型: ${file.type}, 文件路径: ${file.tempFilePath}`);
|
||||||
|
let compressImg = file.tempFilePath;
|
||||||
|
// 图片进行压缩
|
||||||
|
if (file.fileType === 'image') {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
// 压缩图片
|
||||||
|
compressImg = await compressImageUni(file.tempFilePath);
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
// 执行上传
|
||||||
|
let param = {
|
||||||
|
filePath: compressImg,
|
||||||
|
name: 'file',
|
||||||
|
formData: {
|
||||||
|
directory:'polling'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
imgLoading.value=true;
|
||||||
|
minioUpload(param).then(res=>{
|
||||||
|
let data = res.data;
|
||||||
|
mediaArr.value.push(data.fileName);
|
||||||
|
if (file.fileType === 'image') {// 图片
|
||||||
|
imgArr.value.push({
|
||||||
|
shortUrl:minioObj.minioThumbUrl +"/"+data.fileName,
|
||||||
|
url:minioObj.minioUrl +"/"+data.fileName,
|
||||||
|
name:data.fileName
|
||||||
|
})
|
||||||
|
} else if (file.fileType === 'video') {// 视频
|
||||||
|
videoArr.value.push({
|
||||||
|
shortUrl:minioObj.minioThumbUrl +"/"+data.fileName,
|
||||||
|
url:minioObj.minioUrl +"/"+data.fileName,
|
||||||
|
name:data.fileName
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).finally(()=>{
|
||||||
|
imgLoading.value=false;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeMedia = ()=>{
|
||||||
|
imgLoading.value=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插件回调
|
||||||
|
const getMediaArr=(arr)=>{
|
||||||
|
// console.log("插件回调=>",arr)
|
||||||
|
try {
|
||||||
|
arr.forEach(data=>{
|
||||||
|
mediaArr.value.push(data.fileName);
|
||||||
|
if(data.fileType=="image"){
|
||||||
|
imgArr.value.push({
|
||||||
|
shortUrl:minioObj.minioThumbUrl +"/"+data.fileName,
|
||||||
|
url:minioObj.minioUrl +"/"+data.fileName,
|
||||||
|
name:data.fileName
|
||||||
|
})
|
||||||
|
}else if(data.fileType == "video"){
|
||||||
|
videoArr.value.push({
|
||||||
|
shortUrl:minioObj.minioThumbUrl +"/"+data.fileName,
|
||||||
|
url:minioObj.minioUrl +"/"+data.fileName,
|
||||||
|
name:data.fileName
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// console.log(imgArr.value,videoArr.value)
|
||||||
|
imgLoading.value=false;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
imgLoading.value=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 视频或图片删除 根据数组下标删除数组里的某个图片或视频
|
||||||
|
const handleDelete=(arr,index2)=>{
|
||||||
|
arr.splice(index2, 1);
|
||||||
|
let item = arr[index2];
|
||||||
|
mediaArr.value = mediaArr.value.filter(item2=>item2!=item.name);
|
||||||
|
// console.log("删除后=>",mediaArr.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 放大视频或图片
|
||||||
|
let isVisible= ref(false);//放大处理
|
||||||
|
let mediaUrl= ref('');//放大地址
|
||||||
|
let videoShow = ref(true);
|
||||||
|
const showMediaPreview=(item)=>{
|
||||||
|
// console.log("调用放大视频==>",item)
|
||||||
|
isVisible.value = true;
|
||||||
|
videoShow.value = false;
|
||||||
|
mediaUrl.value = item.url
|
||||||
|
}
|
||||||
|
const handlePreviewClose=()=>{
|
||||||
|
isVisible.value = false;
|
||||||
|
videoShow.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交
|
||||||
|
const handleSubmit=()=>{
|
||||||
|
let param = {
|
||||||
|
bugId:bugId.value,
|
||||||
|
logVedio:mediaArr.value.join(","),
|
||||||
|
logDesc:desc.value
|
||||||
|
}
|
||||||
|
// console.log("patrolBugAddLog=>",param)
|
||||||
|
patrolBugAddLog(param).then(res=>{
|
||||||
|
showAlert("新建问题跟踪成功!");
|
||||||
|
uni.navigateBack();
|
||||||
|
}).finally(()=>{
|
||||||
|
hideLoading();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.scroll-h{
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height:calc(100vh - 78px) !important;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
height: calc(100vh - 58px) !important;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
:deep(.mescroll-upwarp){
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.white-bg{
|
||||||
|
width: 680rpx;
|
||||||
|
padding: 15rpx 30rpx 40rpx 40rpx;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white-bg .red-title{
|
||||||
|
margin-bottom:30rpx;
|
||||||
|
color:#FF2B44;
|
||||||
|
font-size:38rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-border{
|
||||||
|
border-bottom:1px solid #E7E7E7;
|
||||||
|
width:710rpx;
|
||||||
|
height: 1px;
|
||||||
|
margin:20rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list{
|
||||||
|
display: flex;
|
||||||
|
font-size:28rpx;
|
||||||
|
}
|
||||||
|
.report-list .r-title{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.report-list text{
|
||||||
|
color:#FF2B44;
|
||||||
|
font-size:28rpx;
|
||||||
|
}
|
||||||
|
.report-list .report-pro{
|
||||||
|
font-size:28rpx;
|
||||||
|
width:16%;
|
||||||
|
/* margin-right:30rpx; */
|
||||||
|
}
|
||||||
|
.report-list .report-right{
|
||||||
|
width:84%;
|
||||||
|
color:#919191;
|
||||||
|
font-size:28rpx;
|
||||||
|
}
|
||||||
|
.report-list .r-input{
|
||||||
|
border:1px solid #E7E7E7;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
width:620rpx;
|
||||||
|
padding:15rpx 25rpx;
|
||||||
|
margin:20rpx 0 30rpx;
|
||||||
|
}
|
||||||
|
.report-list .place-input{
|
||||||
|
color:#BFBFBF;
|
||||||
|
font-size:28rpx;
|
||||||
|
}
|
||||||
|
.report-list .textarea{
|
||||||
|
min-height: 120rpx;
|
||||||
|
}
|
||||||
|
.report-list .r-list{
|
||||||
|
padding: 10rpx 0;
|
||||||
|
}
|
||||||
|
.report-list .r-list:first-child{
|
||||||
|
padding-top:0;
|
||||||
|
}
|
||||||
|
.report-list .r-left{
|
||||||
|
display: flex;
|
||||||
|
font-size:28rpx;
|
||||||
|
color:#919191;
|
||||||
|
}
|
||||||
|
.report-list .r-left view:first-child{
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
.report-list .r-left.r-red{
|
||||||
|
color: #FF2B44;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .r-right{
|
||||||
|
display: flex;
|
||||||
|
font-size:30rpx;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.report-list .r-r-round{
|
||||||
|
width:35rpx;
|
||||||
|
height:35rpx;
|
||||||
|
border:1px solid #BDBDBD;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.report-list .r-r-round.active{
|
||||||
|
border:1px solid #FF2B44;
|
||||||
|
background-color: #FF2B44;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.report-list .r-r-round.active::after{
|
||||||
|
content:"!";
|
||||||
|
position: absolute;
|
||||||
|
top:0;
|
||||||
|
left:0;
|
||||||
|
color:#fff;
|
||||||
|
text-align: center;
|
||||||
|
width:35rpx;
|
||||||
|
height:35rpx;
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
line-height: 30rpx;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
height:30rpx;
|
||||||
|
padding-top:5rpx;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .img-flex{
|
||||||
|
display: flex;
|
||||||
|
flex-flow:row wrap;
|
||||||
|
margin-bottom:30rpx;
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
.report-list .img-show img,
|
||||||
|
.report-list .img-show image,
|
||||||
|
.report-list .img-show video,
|
||||||
|
.report-list .img-show .player-wrapper{
|
||||||
|
width:210rpx;
|
||||||
|
height: 140rpx;
|
||||||
|
}
|
||||||
|
.report-list .img-show :deep(.uni-video-cover-play-button){
|
||||||
|
width:64rpx;
|
||||||
|
height: 64rpx;
|
||||||
|
line-height: 64rpx;
|
||||||
|
font-size:60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .img-con{
|
||||||
|
background-color: #EEEEEE;
|
||||||
|
width:210rpx;
|
||||||
|
height: 140rpx;
|
||||||
|
text-align: center;
|
||||||
|
color:#919191;
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
.report-list .img-con .img-pic{
|
||||||
|
width:76rpx;
|
||||||
|
height: 76rpx;
|
||||||
|
margin-top:30rpx;
|
||||||
|
}
|
||||||
|
.report-list .img-show,
|
||||||
|
.report-list .img-con{
|
||||||
|
width: calc(100% / 3 - 10px); /* 减去一些间隙以避免溢出 */
|
||||||
|
margin:20rpx 10rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .img-show:first-child,
|
||||||
|
.report-list .img-con:first-child{
|
||||||
|
margin-left:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-list .img-show{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.report-list .img-show .img-delete{
|
||||||
|
position: absolute;
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
right:4rpx;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
right:4rpx;
|
||||||
|
/* #endif */
|
||||||
|
top:8rpx;
|
||||||
|
width:34rpx;
|
||||||
|
height:34rpx;
|
||||||
|
line-height:34rpx;
|
||||||
|
border-radius:3rpx;
|
||||||
|
background-color: rgba(0, 0, 0, 0.6);
|
||||||
|
text-align: center;
|
||||||
|
z-index:1;
|
||||||
|
}
|
||||||
|
.report-list .img-show .img-icon{
|
||||||
|
position: absolute;
|
||||||
|
top:50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 64rpx;
|
||||||
|
height:64rpx;
|
||||||
|
margin-left:-32rpx;
|
||||||
|
margin-top:-32rpx;
|
||||||
|
z-index:1;
|
||||||
|
}
|
||||||
|
.report-list .img-show .img-icon img{
|
||||||
|
width: 64rpx;
|
||||||
|
height:64rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-submit{
|
||||||
|
width:400rpx;
|
||||||
|
margin:90rpx auto;
|
||||||
|
}
|
||||||
|
.btn-submit uni-button[type='primary']{
|
||||||
|
background-color: #05A3F4;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
line-height: 2.2;
|
||||||
|
}
|
||||||
|
.btn-submit uni-button:after{
|
||||||
|
border-color:#05A3F4;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -84,7 +84,7 @@ onMounted(() => {
|
|||||||
// 搜索处理
|
// 搜索处理
|
||||||
let searchShow = ref(false);
|
let searchShow = ref(false);
|
||||||
let searchText = ref(undefined);
|
let searchText = ref(undefined);
|
||||||
let searchTypeObj = ref({typeId:3,typeName:'巡检类型'});
|
let searchTypeObj = ref({typeId:4,typeName:'巡检类型'});
|
||||||
let noticeTypeList=ref([
|
let noticeTypeList=ref([
|
||||||
{id:1,name:'日常巡检'},
|
{id:1,name:'日常巡检'},
|
||||||
{id:2,name:'临时巡检'},
|
{id:2,name:'临时巡检'},
|
||||||
@@ -245,10 +245,10 @@ const handleDetail = (item) =>{
|
|||||||
}
|
}
|
||||||
.scroll-h{
|
.scroll-h{
|
||||||
/* #ifdef APP-PLUS */
|
/* #ifdef APP-PLUS */
|
||||||
height: calc(100vh - 130px);
|
height: calc(100vh - 123px) !important;
|
||||||
/* #endif */
|
/* #endif */
|
||||||
/* #ifndef APP-PLUS */
|
/* #ifndef APP-PLUS */
|
||||||
height: calc(100vh - 105px);
|
height: calc(100vh - 105px) !important;
|
||||||
/* #endif */
|
/* #endif */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,4 +295,7 @@ const handleDetail = (item) =>{
|
|||||||
:deep(.mescroll-upwarp){
|
:deep(.mescroll-upwarp){
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
:deep(.mescroll-empty){
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -202,7 +202,7 @@ const initLoad =()=>{
|
|||||||
getSalesTask();
|
getSalesTask();
|
||||||
getCommonServices();
|
getCommonServices();
|
||||||
getNewsList();
|
getNewsList();
|
||||||
// getTaskCount();
|
getTaskCount();
|
||||||
hideLoading();
|
hideLoading();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
hideLoading();
|
hideLoading();
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ import { MINIO_KEY } from '@/enums/cacheEnums';
|
|||||||
import { versionCheck,getBindStatus } from '@/api/auth.js';
|
import { versionCheck,getBindStatus } from '@/api/auth.js';
|
||||||
import { formatIOS } from '@/utils/status.js'
|
import { formatIOS } from '@/utils/status.js'
|
||||||
// import { requestAndroidPermissionAsync,requestAndroidPermission } from '@/utils/common.js'
|
// import { requestAndroidPermissionAsync,requestAndroidPermission } from '@/utils/common.js'
|
||||||
import {showAlert} from '@/utils/message.js'
|
import {showAlert,showToast} from '@/utils/message.js'
|
||||||
|
import {isNetwork,openNetworkSettings} from '@/utils/common.js'
|
||||||
import { minioParam } from '@/api/polling.js'
|
import { minioParam } from '@/api/polling.js'
|
||||||
import { useUserStore } from '@/stores/user';
|
import { useUserStore } from '@/stores/user';
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
@@ -55,6 +56,14 @@ onLoad(async(opt) => {
|
|||||||
// uni.preloadPage({url: "/pages/home/home"});
|
// uni.preloadPage({url: "/pages/home/home"});
|
||||||
|
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
|
let res = await isNetwork();//验证是否有网络
|
||||||
|
if(res==='none'){
|
||||||
|
showAlert('当前网络不可用,请检查网络设置','提示',false,()=>{
|
||||||
|
openNetworkSettings();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//手机通知授权
|
//手机通知授权
|
||||||
noticMsgTool();
|
noticMsgTool();
|
||||||
|
|
||||||
@@ -94,9 +103,9 @@ onLoad(async(opt) => {
|
|||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// 内网才有minio参数
|
// 内网才有minio参数
|
||||||
// if(networkEnv.value==1){
|
if(networkEnv.value==1){
|
||||||
// getMinioParam();
|
getMinioParam();
|
||||||
// }
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ import { AGREEWELCOME_KEY } from '@/enums/cacheEnums';
|
|||||||
import { getNavBarPaddingTop} from '@/utils/system.js'
|
import { getNavBarPaddingTop} from '@/utils/system.js'
|
||||||
import { useUserStore } from '@/stores/user';
|
import { useUserStore } from '@/stores/user';
|
||||||
import encryptObj from '@/utils/encrypt.js'
|
import encryptObj from '@/utils/encrypt.js'
|
||||||
import {showAlert} from '@/utils/message.js'
|
import {showAlert,showToast} from '@/utils/message.js'
|
||||||
|
|
||||||
|
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
@@ -266,7 +266,7 @@ const submitForm = () => {
|
|||||||
//h5测试用 内网-sn123456
|
//h5测试用 内网-sn123456
|
||||||
//公司外网 'f3fca83f-bf56-47f4-a98b-a602ed8bddee' 529a5543-6957-401e-b090-13df6dee5429
|
//公司外网 'f3fca83f-bf56-47f4-a98b-a602ed8bddee' 529a5543-6957-401e-b090-13df6dee5429
|
||||||
//友晟外网 'b97527c8-2ad4-493c-a01c-5f9d0aabaff2'
|
//友晟外网 'b97527c8-2ad4-493c-a01c-5f9d0aabaff2'
|
||||||
param.uniqCode = '9a41dec6-536f-443f-9d98-8dc5c0b18332'//'9a41dec6-536f-443f-9d98-8dc5c0b18332';//'1af78c0a-b878-425f-9dc5-bee42146860a'
|
param.uniqCode = '9a41dec6-536f-443f-9d98-8dc5c0b18332';
|
||||||
let res = await login(param);
|
let res = await login(param);
|
||||||
userStore.login(res);
|
userStore.login(res);
|
||||||
uni.switchTab({ url: '/pages/home/home' })
|
uni.switchTab({ url: '/pages/home/home' })
|
||||||
@@ -302,20 +302,21 @@ const submitForm = () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// showAlert('读取失败:'+res3.msg)
|
showToast('读取失败:'+res3.msg)
|
||||||
console.error('读取失败:', error);
|
console.error('读取失败:', error);
|
||||||
btnLoading.value = false;
|
btnLoading.value = false;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('读取失败:', error);
|
console.error('读取失败:', error);
|
||||||
// showAlert('出错:', error)
|
showToast('err:'+ error)
|
||||||
btnLoading.value = false;
|
btnLoading.value = false;
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.log('表单错误11:', err);
|
console.log('表单错误11:', err);
|
||||||
|
showToast('err:'+ err)
|
||||||
btnLoading.value = false;
|
btnLoading.value = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
src/static/images/business/icon-xjwtsb.png
Normal file
BIN
src/static/images/business/icon-xjwtsb.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.3 KiB |
@@ -1,5 +1,60 @@
|
|||||||
import { showAlert } from '@/utils/message.js'
|
import { showAlert } from '@/utils/message.js'
|
||||||
|
|
||||||
|
|
||||||
|
// 验证是否有网络
|
||||||
|
export const isNetwork=()=>{
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
uni.getNetworkType({
|
||||||
|
success: function (res) {
|
||||||
|
resolve(res.networkType)
|
||||||
|
},fail:function(err){
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开网络设置
|
||||||
|
export const openNetworkSettings = () => {
|
||||||
|
// 根据不同平台打开网络设置
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
// App端
|
||||||
|
const platform = uni.getSystemInfoSync().platform;
|
||||||
|
if (platform === 'ios') {
|
||||||
|
// iOS打开设置页面
|
||||||
|
plus.runtime.openURL('App-Prefs:root')
|
||||||
|
} else if (platform === 'android') {
|
||||||
|
// Android打开网络设置
|
||||||
|
// 方式1:使用原生API
|
||||||
|
const main = plus.android.runtimeMainActivity()
|
||||||
|
const Intent = plus.android.importClass('android.content.Intent')
|
||||||
|
const Settings = plus.android.importClass('android.provider.Settings')
|
||||||
|
const intent = new Intent(Settings.ACTION_WIFI_SETTINGS)
|
||||||
|
main.startActivity(intent)
|
||||||
|
|
||||||
|
// 方式2:使用scheme(某些设备可能不支持)
|
||||||
|
// plus.runtime.openURL('android.settings.WIFI_SETTINGS')
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
// H5端无法直接跳转系统设置,只能提示
|
||||||
|
uni.showToast({
|
||||||
|
title: '请手动打开网络设置',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
// 微信小程序无法跳转系统设置,可以引导用户检查网络
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '请检查手机网络或WiFi连接',
|
||||||
|
showCancel: false
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
// 递归算法
|
// 递归算法
|
||||||
export const initTree = (arr, parentId = '0', id) => {
|
export const initTree = (arr, parentId = '0', id) => {
|
||||||
const tree = [];
|
const tree = [];
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ export default class HttpRequest {
|
|||||||
// console.log("success111=>",response)
|
// console.log("success111=>",response)
|
||||||
if (responseInterceptorsHook && isFunction(responseInterceptorsHook)) {
|
if (responseInterceptorsHook && isFunction(responseInterceptorsHook)) {
|
||||||
try {
|
try {
|
||||||
response = await responseInterceptorsHook(response, mergeConfig);
|
response = await responseInterceptorsHook(response, mergeConfig,options);
|
||||||
resolve(response);
|
resolve(response);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import HttpRequest from './http';
|
import HttpRequest from './http';
|
||||||
import { merge } from 'lodash-es';
|
import { merge } from 'lodash-es';
|
||||||
import { getToken } from '../auth';
|
import { getToken,clearToken } from '../auth';
|
||||||
import { CLIENT_ID } from '@/enums/cacheEnums';
|
import { CLIENT_ID } from '@/enums/cacheEnums';
|
||||||
import { RequestCodeEnum, RequestMethodsEnum } from '@/enums/requestEnums';
|
import { RequestCodeEnum, RequestMethodsEnum,RequestUrlAlertEum } from '@/enums/requestEnums';
|
||||||
import { clearToken } from '@/utils/auth'
|
|
||||||
import { useUserStore } from '@/stores/user'
|
import { useUserStore } from '@/stores/user'
|
||||||
import { useMessage } from '../message';
|
import { useMessage } from '../message';
|
||||||
const message = useMessage();
|
const message = useMessage();
|
||||||
@@ -29,7 +28,7 @@ const requestHooks = {
|
|||||||
return options;
|
return options;
|
||||||
},
|
},
|
||||||
// 响应拦截器
|
// 响应拦截器
|
||||||
responseInterceptorsHook(response, config) {
|
responseInterceptorsHook(response, config,options) {
|
||||||
// console.log("response=>",response)
|
// console.log("response=>",response)
|
||||||
// console.log("response=>config=>",config)
|
// console.log("response=>config=>",config)
|
||||||
const { isTransformResponse, isReturnDefaultResponse, isAuth } = config;
|
const { isTransformResponse, isReturnDefaultResponse, isAuth } = config;
|
||||||
@@ -60,6 +59,13 @@ const requestHooks = {
|
|||||||
return Promise.reject();
|
return Promise.reject();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
// 判断弹窗处理
|
||||||
|
const isUrlFlag = RequestUrlAlertEum.includes(options.url);
|
||||||
|
// console.log("返回处理==>",isUrlFlag,options.url)
|
||||||
|
if(isUrlFlag){
|
||||||
|
return {code,msg};
|
||||||
|
}
|
||||||
|
|
||||||
if(msg)
|
if(msg)
|
||||||
message.alert(msg)
|
message.alert(msg)
|
||||||
else
|
else
|
||||||
@@ -70,6 +76,7 @@ const requestHooks = {
|
|||||||
},
|
},
|
||||||
// 响应异常拦截器
|
// 响应异常拦截器
|
||||||
responseInterceptorsCatchHook(options, err) {
|
responseInterceptorsCatchHook(options, err) {
|
||||||
|
// console.log("responseInterceptorsCatchHook=>",options,err)
|
||||||
if (options.method.toUpperCase() == RequestMethodsEnum.POST) {
|
if (options.method.toUpperCase() == RequestMethodsEnum.POST) {
|
||||||
console.log('请求失败:', err, options);
|
console.log('请求失败:', err, options);
|
||||||
}
|
}
|
||||||
@@ -82,7 +89,7 @@ const defaultOptions = {
|
|||||||
requestOptions: {// 请求配置
|
requestOptions: {// 请求配置
|
||||||
timeout: 10 * 1000,
|
timeout: 10 * 1000,
|
||||||
header: {
|
header: {
|
||||||
version: '1.0.0',
|
// version: '1.0.0',
|
||||||
clientId:`${CLIENT_ID || 2}`, // clientId传2
|
clientId:`${CLIENT_ID || 2}`, // clientId传2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user