Merge branch 'wyfMain-dev'
Some checks failed
Check / lint (push) Has been cancelled
Check / typecheck (push) Has been cancelled
Check / build (build, 18.x, ubuntu-latest) (push) Has been cancelled
Check / build (build, 18.x, windows-latest) (push) Has been cancelled
Check / build (build:app, 18.x, ubuntu-latest) (push) Has been cancelled
Check / build (build:app, 18.x, windows-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 18.x, ubuntu-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 18.x, windows-latest) (push) Has been cancelled
@ -39,7 +39,7 @@
|
|||||||
"quill-mention": "^6.0.2",
|
"quill-mention": "^6.0.2",
|
||||||
"vconsole": "^3.15.1",
|
"vconsole": "^3.15.1",
|
||||||
"vue": "^3.3.8",
|
"vue": "^3.3.8",
|
||||||
"vue-i18n": "^9.6.5"
|
"vue-i18n": "11.0.0-rc.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@dcloudio/types": "^3.4.7",
|
"@dcloudio/types": "^3.4.7",
|
||||||
|
@ -93,8 +93,8 @@ importers:
|
|||||||
specifier: ^3.3.8
|
specifier: ^3.3.8
|
||||||
version: 3.4.35(typescript@5.5.4)
|
version: 3.4.35(typescript@5.5.4)
|
||||||
vue-i18n:
|
vue-i18n:
|
||||||
specifier: ^9.6.5
|
specifier: 11.0.0-rc.1
|
||||||
version: 9.13.1(vue@3.4.35(typescript@5.5.4))
|
version: 11.0.0-rc.1(vue@3.4.35(typescript@5.5.4))
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@dcloudio/types':
|
'@dcloudio/types':
|
||||||
specifier: ^3.4.7
|
specifier: ^3.4.7
|
||||||
@ -1391,26 +1391,26 @@ packages:
|
|||||||
'@iconify/utils@2.1.32':
|
'@iconify/utils@2.1.32':
|
||||||
resolution: {integrity: sha512-LeifFZPPKu28O3AEDpYJNdEbvS4/ojAPyIW+pF/vUpJTYnbTiXUHkCh0bwgFRzKvdpb8H4Fbfd/742++MF4fPQ==}
|
resolution: {integrity: sha512-LeifFZPPKu28O3AEDpYJNdEbvS4/ojAPyIW+pF/vUpJTYnbTiXUHkCh0bwgFRzKvdpb8H4Fbfd/742++MF4fPQ==}
|
||||||
|
|
||||||
|
'@intlify/core-base@11.0.0-rc.1':
|
||||||
|
resolution: {integrity: sha512-fnfZoa9pb1dKM3L1UkDUGLLrPFQ2BK98x4/fMqwS/fktUor34vQR/itPtfv652ZTplenXXLCEYjUYTGfDZgMTQ==}
|
||||||
|
engines: {node: '>= 16'}
|
||||||
|
|
||||||
'@intlify/core-base@9.1.9':
|
'@intlify/core-base@9.1.9':
|
||||||
resolution: {integrity: sha512-x5T0p/Ja0S8hs5xs+ImKyYckVkL4CzcEXykVYYV6rcbXxJTe2o58IquSqX9bdncVKbRZP7GlBU1EcRaQEEJ+vw==}
|
resolution: {integrity: sha512-x5T0p/Ja0S8hs5xs+ImKyYckVkL4CzcEXykVYYV6rcbXxJTe2o58IquSqX9bdncVKbRZP7GlBU1EcRaQEEJ+vw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
'@intlify/core-base@9.13.1':
|
|
||||||
resolution: {integrity: sha512-+bcQRkJO9pcX8d0gel9ZNfrzU22sZFSA0WVhfXrf5jdJOS24a+Bp8pozuS9sBI9Hk/tGz83pgKfmqcn/Ci7/8w==}
|
|
||||||
engines: {node: '>= 16'}
|
|
||||||
|
|
||||||
'@intlify/devtools-if@9.1.9':
|
'@intlify/devtools-if@9.1.9':
|
||||||
resolution: {integrity: sha512-oKSMKjttG3Ut/1UGEZjSdghuP3fwA15zpDPcjkf/1FjlOIm6uIBGMNS5jXzsZy593u+P/YcnrZD6cD3IVFz9vQ==}
|
resolution: {integrity: sha512-oKSMKjttG3Ut/1UGEZjSdghuP3fwA15zpDPcjkf/1FjlOIm6uIBGMNS5jXzsZy593u+P/YcnrZD6cD3IVFz9vQ==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
|
'@intlify/message-compiler@11.0.0-rc.1':
|
||||||
|
resolution: {integrity: sha512-TGw2uBfuTFTegZf/BHtUQBEKxl7Q/dVGLoqRIdw8lFsp9g/53sYn5iD+0HxIzdYjbWL6BTJMXCPUHp9PxDTRPw==}
|
||||||
|
engines: {node: '>= 16'}
|
||||||
|
|
||||||
'@intlify/message-compiler@9.1.9':
|
'@intlify/message-compiler@9.1.9':
|
||||||
resolution: {integrity: sha512-6YgCMF46Xd0IH2hMRLCssZI3gFG4aywidoWQ3QP4RGYQXQYYfFC54DxhSgfIPpVoPLQ+4AD29eoYmhiHZ+qLFQ==}
|
resolution: {integrity: sha512-6YgCMF46Xd0IH2hMRLCssZI3gFG4aywidoWQ3QP4RGYQXQYYfFC54DxhSgfIPpVoPLQ+4AD29eoYmhiHZ+qLFQ==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
'@intlify/message-compiler@9.13.1':
|
|
||||||
resolution: {integrity: sha512-SKsVa4ajYGBVm7sHMXd5qX70O2XXjm55zdZB3VeMFCvQyvLew/dLvq3MqnaIsTMF1VkkOb9Ttr6tHcMlyPDL9w==}
|
|
||||||
engines: {node: '>= 16'}
|
|
||||||
|
|
||||||
'@intlify/message-resolver@9.1.9':
|
'@intlify/message-resolver@9.1.9':
|
||||||
resolution: {integrity: sha512-Lx/DBpigeK0sz2BBbzv5mu9/dAlt98HxwbG7xLawC3O2xMF9MNWU5FtOziwYG6TDIjNq0O/3ZbOJAxwITIWXEA==}
|
resolution: {integrity: sha512-Lx/DBpigeK0sz2BBbzv5mu9/dAlt98HxwbG7xLawC3O2xMF9MNWU5FtOziwYG6TDIjNq0O/3ZbOJAxwITIWXEA==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
@ -1419,14 +1419,14 @@ packages:
|
|||||||
resolution: {integrity: sha512-XgPw8+UlHCiie3fI41HPVa/VDJb3/aSH7bLhY1hJvlvNV713PFtb4p4Jo+rlE0gAoMsMCGcsiT982fImolSltg==}
|
resolution: {integrity: sha512-XgPw8+UlHCiie3fI41HPVa/VDJb3/aSH7bLhY1hJvlvNV713PFtb4p4Jo+rlE0gAoMsMCGcsiT982fImolSltg==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
|
'@intlify/shared@11.0.0-rc.1':
|
||||||
|
resolution: {integrity: sha512-8tR1xe7ZEbkabTuE/tNhzpolygUn9OaYp9yuYAF4MgDNZg06C3Qny80bes2/e9/Wm3aVkPUlCw6WgU7mQd0yEg==}
|
||||||
|
engines: {node: '>= 16'}
|
||||||
|
|
||||||
'@intlify/shared@9.1.9':
|
'@intlify/shared@9.1.9':
|
||||||
resolution: {integrity: sha512-xKGM1d0EAxdDFCWedcYXOm6V5Pfw/TMudd6/qCdEb4tv0hk9EKeg7lwQF1azE0dP2phvx0yXxrt7UQK+IZjNdw==}
|
resolution: {integrity: sha512-xKGM1d0EAxdDFCWedcYXOm6V5Pfw/TMudd6/qCdEb4tv0hk9EKeg7lwQF1azE0dP2phvx0yXxrt7UQK+IZjNdw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
'@intlify/shared@9.13.1':
|
|
||||||
resolution: {integrity: sha512-u3b6BKGhE6j/JeRU6C/RL2FgyJfy6LakbtfeVF8fJXURpZZTzfh3e05J0bu0XPw447Q6/WUp3C4ajv4TMS4YsQ==}
|
|
||||||
engines: {node: '>= 16'}
|
|
||||||
|
|
||||||
'@intlify/vue-devtools@9.1.9':
|
'@intlify/vue-devtools@9.1.9':
|
||||||
resolution: {integrity: sha512-YPehH9uL4vZcGXky4Ev5qQIITnHKIvsD2GKGXgqf+05osMUI6WSEQHaN9USRa318Rs8RyyPCiDfmA0hRu3k7og==}
|
resolution: {integrity: sha512-YPehH9uL4vZcGXky4Ev5qQIITnHKIvsD2GKGXgqf+05osMUI6WSEQHaN9USRa318Rs8RyyPCiDfmA0hRu3k7og==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
@ -4819,8 +4819,8 @@ packages:
|
|||||||
'@vue/composition-api':
|
'@vue/composition-api':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
vue-i18n@9.13.1:
|
vue-i18n@11.0.0-rc.1:
|
||||||
resolution: {integrity: sha512-mh0GIxx0wPtPlcB1q4k277y0iKgo25xmDPWioVVYanjPufDBpvu5ySTjP5wOrSvlYQ2m1xI+CFhGdauv/61uQg==}
|
resolution: {integrity: sha512-qbdCbA537HEdr2yXQ4ec/OMDsoHjod1DwnWbrf+l4Cu/O7CYTCKsOyITUm3RmrCJgRnoVycuR6i/JWdNTJvD5g==}
|
||||||
engines: {node: '>= 16'}
|
engines: {node: '>= 16'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: ^3.0.0
|
vue: ^3.0.0
|
||||||
@ -6730,6 +6730,11 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
'@intlify/core-base@11.0.0-rc.1':
|
||||||
|
dependencies:
|
||||||
|
'@intlify/message-compiler': 11.0.0-rc.1
|
||||||
|
'@intlify/shared': 11.0.0-rc.1
|
||||||
|
|
||||||
'@intlify/core-base@9.1.9':
|
'@intlify/core-base@9.1.9':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@intlify/devtools-if': 9.1.9
|
'@intlify/devtools-if': 9.1.9
|
||||||
@ -6739,26 +6744,21 @@ snapshots:
|
|||||||
'@intlify/shared': 9.1.9
|
'@intlify/shared': 9.1.9
|
||||||
'@intlify/vue-devtools': 9.1.9
|
'@intlify/vue-devtools': 9.1.9
|
||||||
|
|
||||||
'@intlify/core-base@9.13.1':
|
|
||||||
dependencies:
|
|
||||||
'@intlify/message-compiler': 9.13.1
|
|
||||||
'@intlify/shared': 9.13.1
|
|
||||||
|
|
||||||
'@intlify/devtools-if@9.1.9':
|
'@intlify/devtools-if@9.1.9':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@intlify/shared': 9.1.9
|
'@intlify/shared': 9.1.9
|
||||||
|
|
||||||
|
'@intlify/message-compiler@11.0.0-rc.1':
|
||||||
|
dependencies:
|
||||||
|
'@intlify/shared': 11.0.0-rc.1
|
||||||
|
source-map-js: 1.2.0
|
||||||
|
|
||||||
'@intlify/message-compiler@9.1.9':
|
'@intlify/message-compiler@9.1.9':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@intlify/message-resolver': 9.1.9
|
'@intlify/message-resolver': 9.1.9
|
||||||
'@intlify/shared': 9.1.9
|
'@intlify/shared': 9.1.9
|
||||||
source-map: 0.6.1
|
source-map: 0.6.1
|
||||||
|
|
||||||
'@intlify/message-compiler@9.13.1':
|
|
||||||
dependencies:
|
|
||||||
'@intlify/shared': 9.13.1
|
|
||||||
source-map-js: 1.2.0
|
|
||||||
|
|
||||||
'@intlify/message-resolver@9.1.9': {}
|
'@intlify/message-resolver@9.1.9': {}
|
||||||
|
|
||||||
'@intlify/runtime@9.1.9':
|
'@intlify/runtime@9.1.9':
|
||||||
@ -6767,9 +6767,9 @@ snapshots:
|
|||||||
'@intlify/message-resolver': 9.1.9
|
'@intlify/message-resolver': 9.1.9
|
||||||
'@intlify/shared': 9.1.9
|
'@intlify/shared': 9.1.9
|
||||||
|
|
||||||
'@intlify/shared@9.1.9': {}
|
'@intlify/shared@11.0.0-rc.1': {}
|
||||||
|
|
||||||
'@intlify/shared@9.13.1': {}
|
'@intlify/shared@9.1.9': {}
|
||||||
|
|
||||||
'@intlify/vue-devtools@9.1.9':
|
'@intlify/vue-devtools@9.1.9':
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -10890,10 +10890,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.4.35(typescript@5.5.4)
|
vue: 3.4.35(typescript@5.5.4)
|
||||||
|
|
||||||
vue-i18n@9.13.1(vue@3.4.35(typescript@5.5.4)):
|
vue-i18n@11.0.0-rc.1(vue@3.4.35(typescript@5.5.4)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@intlify/core-base': 9.13.1
|
'@intlify/core-base': 11.0.0-rc.1
|
||||||
'@intlify/shared': 9.13.1
|
'@intlify/shared': 11.0.0-rc.1
|
||||||
'@vue/devtools-api': 6.6.3
|
'@vue/devtools-api': 6.6.3
|
||||||
vue: 3.4.35(typescript@5.5.4)
|
vue: 3.4.35(typescript@5.5.4)
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ init()
|
|||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "@/static/css/color.scss";
|
@import "@/static/css/color.scss";
|
||||||
|
@import "@/static/css/font.scss";
|
||||||
/* #ifdef APP-NVUE */
|
/* #ifdef APP-NVUE */
|
||||||
@import '@/uni_modules/tmui/scss/nvue.css';
|
@import '@/uni_modules/tmui/scss/nvue.css';
|
||||||
/* #endif */
|
/* #endif */
|
||||||
|
@ -207,6 +207,7 @@ export const ServeGroupAssignAdmin = (data) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//指定人员禁言
|
||||||
export const ServeGroupNoSpeak = (data) => {
|
export const ServeGroupNoSpeak = (data) => {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/v1/group/no-speak',
|
url: '/api/v1/group/no-speak',
|
||||||
@ -214,4 +215,3 @@ export const ServeGroupNoSpeak = (data) => {
|
|||||||
data,
|
data,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
47
src/api/search/index.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import request from '@/service/index.js'
|
||||||
|
import qs from 'qs'
|
||||||
|
|
||||||
|
// ES搜索聊天记录-主页搜索什么都有
|
||||||
|
export const ServeSeachQueryAll = (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/v1/elasticsearch/query-all',
|
||||||
|
method: 'POST',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ES搜索用户数据
|
||||||
|
export const ServeQueryUser = (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/v1/elasticsearch/query-user',
|
||||||
|
method: 'POST',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ES搜索群组数据
|
||||||
|
export const ServeQueryGroup = (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/v1/elasticsearch/query-group',
|
||||||
|
method: 'POST',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ES搜索聊天记录-指定用户、指定群、群与用户概览
|
||||||
|
export const ServeTalkRecord = (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/v1/elasticsearch/query-talk-record',
|
||||||
|
method: 'POST',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//查看存在聊天记录的天数
|
||||||
|
export const ServeTalkDate = (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/v1/talk/date',
|
||||||
|
method: 'POST',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
42
src/components/custom-btn/custom-btn.vue
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<template>
|
||||||
|
<div class="custom-btn" :class="props.isBottom ? 'custom-btn-bottom' : ''">
|
||||||
|
<wd-button custom-class="custom-btn-class" @click="clickBtn">{{ props.btnText }}</wd-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
import { defineProps, defineEmits } from 'vue'
|
||||||
|
const state = reactive({})
|
||||||
|
const emits = defineEmits(['clickBtn'])
|
||||||
|
const props = defineProps({
|
||||||
|
isBottom: false, //是否底部按钮
|
||||||
|
btnText: '', //按钮文字
|
||||||
|
})
|
||||||
|
|
||||||
|
//点击
|
||||||
|
const clickBtn = () => {
|
||||||
|
emits('clickBtn')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.custom-btn {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
.custom-btn-class {
|
||||||
|
background-color: $theme-primary;
|
||||||
|
padding: 18rpx 185rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
box-shadow: 0 6px 12px 2px rgba(188, 188, 188, 0.08);
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 40rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.custom-btn-bottom {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 14rpx 0 72rpx;
|
||||||
|
}
|
||||||
|
</style>
|
58
src/components/custom-input/custom-input.vue
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<div class="custom-search-input">
|
||||||
|
<tm-input
|
||||||
|
class="search-input"
|
||||||
|
placeholder="请输入…"
|
||||||
|
color="#F9F9FD"
|
||||||
|
:round="1"
|
||||||
|
prefix="tmicon-search"
|
||||||
|
prefixColor="#46299D"
|
||||||
|
:prefixLabel="props?.first_talk_record_infos?.receiver_name"
|
||||||
|
v-model.lazy="state.searchText"
|
||||||
|
@input="inputSearchText"
|
||||||
|
:showClear="true"
|
||||||
|
@clear="clearInput"
|
||||||
|
></tm-input>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { defineProps, defineEmits, reactive, watch } from 'vue'
|
||||||
|
const props = defineProps({
|
||||||
|
searchText: String,
|
||||||
|
first_talk_record_infos: Object,
|
||||||
|
})
|
||||||
|
const state = reactive({
|
||||||
|
searchText: '', //搜索内容
|
||||||
|
})
|
||||||
|
const emits = defineEmits(['inputSearchText'])
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.searchText,
|
||||||
|
(newSearchText) => {
|
||||||
|
state.searchText = newSearchText
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
//清除输入的搜索内容
|
||||||
|
const clearInput = () => {
|
||||||
|
inputSearchText('')
|
||||||
|
}
|
||||||
|
|
||||||
|
//输入搜索文本
|
||||||
|
const inputSearchText = (e) => {
|
||||||
|
emits('inputSearchText', e)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.custom-search-input {
|
||||||
|
width: 100%;
|
||||||
|
.search-input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input::v-deep .tmicon-times-circle-fill::before {
|
||||||
|
content: '\e82a';
|
||||||
|
color: #d2d2d5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -74,16 +74,109 @@
|
|||||||
"path": "pages/login/index",
|
"path": "pages/login/index",
|
||||||
"type": "page",
|
"type": "page",
|
||||||
"style": {}
|
"style": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/search/index",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/search/moreResult/moreResult",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/search/moreResult/moreResultDetail",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/search/searchByCondition/index",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/chatSettings/index",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/chatSettings/groupManage/manageNotice",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/chatSettings/groupManage/editGroupName",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/chatSettings/groupManage/editAvatar",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/chatSettings/groupManage/manageGroupMembers",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/chatSettings/groupManage/manageGroupSilence",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/chatSettings/groupManage/selectMembers",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/chatSettings/groupManage/manageGroupAdmin",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
],
|
],
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
"backgroundColor": "#FFFFFF",
|
"backgroundColor": "#FFFFFF",
|
||||||
"navigationBarBackgroundColor": "#FFFFFF",
|
"navigationBarBackgroundColor": "#FFFFFF",
|
||||||
"navigationBarTextstyle": "black",
|
"navigationBarTextstyle": "black",
|
||||||
"navigationBarTitleText": ""
|
"navigationBarTitleText": ""
|
||||||
|
|
||||||
},
|
},
|
||||||
"subPackages": []
|
"subPackages": []
|
||||||
}
|
}
|
||||||
|
117
src/pages/chatSettings/components/groupMembersList.vue
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<template>
|
||||||
|
<div class="group-member-list">
|
||||||
|
<div
|
||||||
|
class="group-member-list-each"
|
||||||
|
v-for="(memberItem, memberIndex) in props?.memberList"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="group-member-each"
|
||||||
|
v-if="
|
||||||
|
props.memberListsLimit ? memberIndex < props.memberListsLimit : true
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="group-member-avatar">
|
||||||
|
<img v-if="memberItem.avatar" :src="memberItem.avatar" />
|
||||||
|
<span v-if="!memberItem.avatar" class="text-[24rpx] font-bold">
|
||||||
|
{{
|
||||||
|
memberItem.nickname.length >= 2
|
||||||
|
? memberItem.nickname.slice(-2)
|
||||||
|
: memberItem.nickname
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="group-member-tag" v-if="memberIndex < 3">
|
||||||
|
<span class="text-[16rpx] font-regular">
|
||||||
|
{{ $t('group.identify.admin') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="group-member-name">
|
||||||
|
<span class="text-[24rpx] font-regular">
|
||||||
|
{{ memberItem.nickname }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { defineProps } from 'vue'
|
||||||
|
const props = defineProps({
|
||||||
|
memberList: Array, //人员列表
|
||||||
|
memberListsLimit: Number, //人员列表数量限制
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.group-member-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
.group-member-list-each {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: calc(100% / 5);
|
||||||
|
.group-member-each {
|
||||||
|
padding: 32rpx 0 0;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
.group-member-avatar {
|
||||||
|
width: 72rpx;
|
||||||
|
height: 72rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
background: linear-gradient(to right, #674bbc, #46299d);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
line-height: 34rpx;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.group-member-tag {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 34rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: #cf3050;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 0 12rpx;
|
||||||
|
span {
|
||||||
|
line-height: 22rpx;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.group-member-name {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 8rpx 0 0;
|
||||||
|
width: 100%;
|
||||||
|
span {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
line-height: 34rpx;
|
||||||
|
color: #919191;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
142
src/pages/chatSettings/components/select-member-item.vue
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="select-member-item"
|
||||||
|
@click="clickItem(props?.memberItem)"
|
||||||
|
:class="
|
||||||
|
props.itemStyle === 'card'
|
||||||
|
? 'select-member-item-card'
|
||||||
|
: 'select-member-item-list'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="member-info">
|
||||||
|
<slot name="left"></slot>
|
||||||
|
<div
|
||||||
|
class="select-member-item-avatar"
|
||||||
|
v-if="
|
||||||
|
props?.manageType === 'silence' ||
|
||||||
|
props?.manageType === 'searchRecord'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<img v-if="avatarImg !== 'textImg'" :src="avatarImg" />
|
||||||
|
<span v-if="avatarImg === 'textImg'" class="text-[24rpx] font-bold">
|
||||||
|
{{ imgText }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="select-member-item-name"
|
||||||
|
v-if="
|
||||||
|
props?.manageType === 'silence' ||
|
||||||
|
props?.manageType === 'searchRecord'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<span class="text-[28rpx] font-medium">{{ nameText }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="operate-btns">
|
||||||
|
<div class="btn-undo-silence">
|
||||||
|
<span v-if="props?.memberItem?.is_mute === 1">
|
||||||
|
{{ $t('chatSettings.btn.undoSilence') }}
|
||||||
|
</span>
|
||||||
|
<span v-if="props?.memberItem?.is_mute === 1">
|
||||||
|
{{ $t('silence.tag.hasDone') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { computed, defineProps, defineEmits } from 'vue'
|
||||||
|
import { onMounted, reactive } from 'vue'
|
||||||
|
|
||||||
|
const emits = defineEmits(['clickItem'])
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
memberItem: Object, //人员
|
||||||
|
manageType: String, //管理类型
|
||||||
|
itemStyle: String,
|
||||||
|
})
|
||||||
|
onMounted(() => {})
|
||||||
|
|
||||||
|
//头像
|
||||||
|
const avatarImg = computed(() => {
|
||||||
|
let avatar_img = props?.memberItem?.avatar
|
||||||
|
if (!avatar_img) {
|
||||||
|
avatar_img = 'textImg'
|
||||||
|
}
|
||||||
|
return avatar_img
|
||||||
|
})
|
||||||
|
|
||||||
|
//名字
|
||||||
|
const nameText = computed(() => {
|
||||||
|
let name = props?.memberItem?.nickname
|
||||||
|
return name
|
||||||
|
})
|
||||||
|
|
||||||
|
//文字头像
|
||||||
|
const imgText = computed(() => {
|
||||||
|
return nameText.value.length >= 2 ? nameText.value.slice(-2) : nameText.value
|
||||||
|
})
|
||||||
|
|
||||||
|
//点击item
|
||||||
|
const clickItem = () => {
|
||||||
|
emits('clickItem')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.select-member-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 18rpx 34rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100%;
|
||||||
|
.member-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
.select-member-item-avatar {
|
||||||
|
background: linear-gradient(to right, #674bbc, #46299d);
|
||||||
|
width: 72rpx;
|
||||||
|
height: 72rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 20rpx 0 0;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
color: #fff;
|
||||||
|
line-height: 34rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.select-member-item-name {
|
||||||
|
span {
|
||||||
|
color: $theme-text;
|
||||||
|
line-height: 40rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.operate-btns {
|
||||||
|
.btn-undo-silence {
|
||||||
|
span {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-member-item-card {
|
||||||
|
margin: 20rpx 0 0;
|
||||||
|
box-shadow: 0 6px 12px 2px rgba(188, 188, 188, 0.08);
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
.select-member-item-list {
|
||||||
|
border-bottom: 1px solid $theme-border-color;
|
||||||
|
}
|
||||||
|
</style>
|
118
src/pages/chatSettings/components/settingFormItem.vue
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<template>
|
||||||
|
<div class="setting-form-item">
|
||||||
|
<div class="item-main">
|
||||||
|
<div class="item-main-label">
|
||||||
|
<span class="text-[32rpx] font-regular">{{ props?.item?.label }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="item-main-value" @click="toManagePage(props?.item)">
|
||||||
|
<span class="text-[32rpx] font-regular" v-if="props?.item?.value">
|
||||||
|
{{ props?.item?.value }}
|
||||||
|
</span>
|
||||||
|
<img
|
||||||
|
v-if="props?.item?.hasPointer"
|
||||||
|
src="/src/static/image/chatSettings/pointer.png"
|
||||||
|
/>
|
||||||
|
<tm-switch
|
||||||
|
:width="88"
|
||||||
|
:height="48"
|
||||||
|
v-if="props?.item?.customInfo && props?.item?.customInfo === 'switch'"
|
||||||
|
barIcon=""
|
||||||
|
color="#46299D"
|
||||||
|
unCheckedColor="#EEEEEE"
|
||||||
|
:modelValue="modelValue"
|
||||||
|
@change="changeSwitch($event, props?.item)"
|
||||||
|
></tm-switch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-sub" v-if="props?.item?.subValue">
|
||||||
|
<span class="text-[32rpx] font-regular">{{ props?.item?.subValue }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { defineProps, defineEmits, computed } from 'vue'
|
||||||
|
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
item: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sessionInfo: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const emits = defineEmits(['toManagePage', 'changeSwitch'])
|
||||||
|
const toManagePage = (item) => {
|
||||||
|
emits('toManagePage', item.label)
|
||||||
|
}
|
||||||
|
const modelValue = computed(() => {
|
||||||
|
let switchStatus = false
|
||||||
|
if (
|
||||||
|
props?.item?.label === t('chat.settings.topSession') &&
|
||||||
|
props?.sessionInfo?.is_top == 1
|
||||||
|
) {
|
||||||
|
switchStatus = true
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
props?.item?.label === t('chat.settings.messageNoDisturb') &&
|
||||||
|
props?.sessionInfo?.is_disturb == 1
|
||||||
|
) {
|
||||||
|
switchStatus = true
|
||||||
|
}
|
||||||
|
return switchStatus
|
||||||
|
})
|
||||||
|
|
||||||
|
//切换开关选择
|
||||||
|
const changeSwitch = (e, item) => {
|
||||||
|
emits('changeSwitch', e, item.label)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.setting-form-item {
|
||||||
|
.item-main {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
.item-main-label {
|
||||||
|
flex-shrink: 0;
|
||||||
|
span {
|
||||||
|
line-height: 44rpx;
|
||||||
|
color: $theme-text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.item-main-value {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
span {
|
||||||
|
line-height: 44rpx;
|
||||||
|
color: #747474;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
width: 11rpx;
|
||||||
|
height: 18rpx;
|
||||||
|
margin: 0 0 0 32rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-sub {
|
||||||
|
margin: 28rpx 0 0;
|
||||||
|
span {
|
||||||
|
line-height: 44rpx;
|
||||||
|
color: #747474;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
95
src/pages/chatSettings/groupManage/editAvatar.vue
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<template>
|
||||||
|
<div class="outer-layer manage-group-info-page">
|
||||||
|
<div class="root">
|
||||||
|
<ZPaging ref="zPaging" :show-scrollbar="false">
|
||||||
|
<template #top>
|
||||||
|
<tm-navbar :hideBack="false" hideHome title="" :leftWidth="220">
|
||||||
|
<div class="navBar-title flex flex-col items-center justify-center">
|
||||||
|
<span class="text-[34rpx] font-medium">
|
||||||
|
{{ $t('chat.settings.editAvatar') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</tm-navbar>
|
||||||
|
</template>
|
||||||
|
<div class="edit-group-info">
|
||||||
|
<div class="group-avatar">
|
||||||
|
<img :src="state.groupAvatar" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<customBtn :btnText="$t('button.text.edit')"></customBtn>
|
||||||
|
<template #bottom>
|
||||||
|
<div class="app-logo-icon">
|
||||||
|
<img src="/src/static/image/chatSettings/app-icon.png" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ZPaging>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import customBtn from '@/components/custom-btn/custom-btn.vue'
|
||||||
|
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
pageTitle: '', //页面标题
|
||||||
|
groupAvatar: '', //群头像
|
||||||
|
groupName: '', //群名称
|
||||||
|
})
|
||||||
|
|
||||||
|
onLoad((options) => {
|
||||||
|
console.log(options)
|
||||||
|
if (options.groupAvatar) {
|
||||||
|
state.groupAvatar = options.groupAvatar
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//点击清空群名称输入
|
||||||
|
const clearGroupNameInput = () => {
|
||||||
|
state.groupName = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击确认修改
|
||||||
|
const confirmEdit = () => {
|
||||||
|
console.log(state.groupName)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.outer-layer {
|
||||||
|
flex: 1;
|
||||||
|
background-image: url('@/static/image/clockIn/z3280@3x.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-group-info {
|
||||||
|
margin: 158rpx 94rpx 100rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 6px 12px 2px rgba(0, 0, 0, 0.16);
|
||||||
|
padding: 50rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
.group-avatar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
img {
|
||||||
|
width: 460rpx;
|
||||||
|
height: 460rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-logo-icon {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 0 44rpx;
|
||||||
|
img {
|
||||||
|
width: 72rpx;
|
||||||
|
height: 72rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
127
src/pages/chatSettings/groupManage/editGroupName.vue
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
<template>
|
||||||
|
<div class="outer-layer manage-group-info-page">
|
||||||
|
<div class="root">
|
||||||
|
<ZPaging ref="zPaging" :show-scrollbar="false">
|
||||||
|
<template #top>
|
||||||
|
<tm-navbar :hideBack="false" hideHome title="" :leftWidth="220">
|
||||||
|
<div class="navBar-title flex flex-col items-center justify-center">
|
||||||
|
<span class="text-[34rpx] font-medium">
|
||||||
|
{{ $t('chat.settings.editGroupName') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</tm-navbar>
|
||||||
|
</template>
|
||||||
|
<div class="edit-group-info">
|
||||||
|
<div class="group-avatar">
|
||||||
|
<img :src="state.groupAvatar" />
|
||||||
|
</div>
|
||||||
|
<div class="group-name">
|
||||||
|
<span class="text-[28rpx] font-medium">
|
||||||
|
{{ $t('chat.settings.groupName') }}
|
||||||
|
</span>
|
||||||
|
<div class="groupNameInputArea">
|
||||||
|
<input
|
||||||
|
class="groupNameInput"
|
||||||
|
:placeholder="$t('edit.groupName.placeholder')"
|
||||||
|
placeholder-style="color:#B4B4B4;font-size:28rpx;font-weight:500;line-height:40rpx;"
|
||||||
|
v-model="state.groupName"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
class="groupName-input-clearBtn"
|
||||||
|
src="/src/static/image/chatSettings/clear-btn.png"
|
||||||
|
@click="clearGroupNameInput"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template #bottom>
|
||||||
|
<customBtn
|
||||||
|
:isBottom="true"
|
||||||
|
:btnText="$t('ok')"
|
||||||
|
@clickBtn="confirmEdit"
|
||||||
|
></customBtn>
|
||||||
|
</template>
|
||||||
|
</ZPaging>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import customBtn from '@/components/custom-btn/custom-btn.vue'
|
||||||
|
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
pageTitle: '', //页面标题
|
||||||
|
groupAvatar: '', //群头像
|
||||||
|
groupName: '', //群名称
|
||||||
|
})
|
||||||
|
|
||||||
|
onLoad((options) => {
|
||||||
|
console.log(options)
|
||||||
|
if (options.groupAvatar) {
|
||||||
|
state.groupAvatar = options.groupAvatar
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//点击清空群名称输入
|
||||||
|
const clearGroupNameInput = () => {
|
||||||
|
state.groupName = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击确认修改
|
||||||
|
const confirmEdit = () => {
|
||||||
|
console.log(state.groupName)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.outer-layer {
|
||||||
|
flex: 1;
|
||||||
|
background-image: url('@/static/image/clockIn/z3280@3x.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-group-info {
|
||||||
|
.group-avatar {
|
||||||
|
padding: 250rpx 0 88rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
img {
|
||||||
|
width: 192rpx;
|
||||||
|
height: 192rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.group-name {
|
||||||
|
padding: 0 32rpx;
|
||||||
|
span {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 32rpx 10rpx;
|
||||||
|
color: $theme-text;
|
||||||
|
}
|
||||||
|
.groupNameInputArea {
|
||||||
|
position: relative;
|
||||||
|
.groupNameInput {
|
||||||
|
background-color: #fff;
|
||||||
|
height: 110rpx;
|
||||||
|
box-shadow: 0 6px 12px 2px rgba(188, 188, 188, 0.08);
|
||||||
|
padding: 0 74rpx 0 32rpx;
|
||||||
|
color: #B747474;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 40rpx;
|
||||||
|
}
|
||||||
|
.groupName-input-clearBtn {
|
||||||
|
position: absolute;
|
||||||
|
right: 22rpx;
|
||||||
|
top: 40rpx;
|
||||||
|
width: 30rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
106
src/pages/chatSettings/groupManage/manageGroupAdmin.vue
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<template>
|
||||||
|
<div class="outer-layer manage-group-silence-page">
|
||||||
|
<div class="root">
|
||||||
|
<ZPaging ref="zPaging" :show-scrollbar="false">
|
||||||
|
<template #top>
|
||||||
|
<tm-navbar :hideBack="false" hideHome title="" :leftWidth="220">
|
||||||
|
<div class="navBar-title flex flex-col items-center justify-center">
|
||||||
|
<span class="text-[34rpx] font-medium">
|
||||||
|
{{ $t('chat.settings.groupAdmin') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</tm-navbar>
|
||||||
|
</template>
|
||||||
|
<div class="manage-group-silence">
|
||||||
|
<span class="manage-group-silence-title text-[28rpx] font-regular">
|
||||||
|
{{ $t('chat.settings.groupAdmin') }}
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="add-silence-member-btn chat-settings-card"
|
||||||
|
@click="toSelectMembersPage"
|
||||||
|
>
|
||||||
|
<img src="/src/static/image/chatSettings/add-btn.png" />
|
||||||
|
<span class="text-[28rpx] font-medium">
|
||||||
|
{{ $t('chat.manage.addAdmin') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ZPaging>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { computed, onMounted, reactive } from 'vue'
|
||||||
|
|
||||||
|
import { useGroupStore, useDialogueStore } from '@/store'
|
||||||
|
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const groupStore = useGroupStore()
|
||||||
|
const dialogueStore = useDialogueStore()
|
||||||
|
|
||||||
|
const dialogueParams = reactive({
|
||||||
|
adminList: computed(() => dialogueStore.getAdminList),
|
||||||
|
})
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
silenceAllBtn: null, //全员禁言按钮
|
||||||
|
})
|
||||||
|
|
||||||
|
onLoad((options) => {
|
||||||
|
console.log(options)
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
console.log(dialogueParams.adminList)
|
||||||
|
})
|
||||||
|
|
||||||
|
//点击跳转到添加禁言成员页面
|
||||||
|
const toSelectMembersPage = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/chatSettings/groupManage/selectMembers?manageType=admin',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.outer-layer {
|
||||||
|
flex: 1;
|
||||||
|
background-image: url('@/static/image/clockIn/z3280@3x.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manage-group-silence {
|
||||||
|
padding: 20rpx 32rpx;
|
||||||
|
.manage-group-silence-title {
|
||||||
|
line-height: 40rpx;
|
||||||
|
color: #959598;
|
||||||
|
}
|
||||||
|
.add-silence-member-btn {
|
||||||
|
padding: 32rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
img {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
margin: 0 22rpx 0 0;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
line-height: 40rpx;
|
||||||
|
color: $theme-text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.chat-settings-card {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx 0 0;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
box-shadow: 0 6px 12px 2px rgba(188, 188, 188, 0.08);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
58
src/pages/chatSettings/groupManage/manageGroupMembers.vue
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<div class="outer-layer manage-group-members-page">
|
||||||
|
<div class="root">
|
||||||
|
<ZPaging
|
||||||
|
ref="zPaging"
|
||||||
|
:show-scrollbar="false"
|
||||||
|
:use-virtual-list="true"
|
||||||
|
:virtual-list-col="5"
|
||||||
|
:auto="false"
|
||||||
|
:refresher-enabled="false"
|
||||||
|
:loading-more-enabled="false"
|
||||||
|
>
|
||||||
|
<template #top>
|
||||||
|
<tm-navbar :hideBack="false" hideHome title="" :leftWidth="220">
|
||||||
|
<div class="navBar-title flex flex-col items-center justify-center">
|
||||||
|
<span class="text-[34rpx] font-medium">
|
||||||
|
{{ $t('chat.settings.groupMember') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</tm-navbar>
|
||||||
|
</template>
|
||||||
|
<div class="group-members-list">
|
||||||
|
<groupMemberList
|
||||||
|
:memberList="talkParams?.memberList"
|
||||||
|
></groupMemberList>
|
||||||
|
</div>
|
||||||
|
</ZPaging>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import groupMemberList from '../components/groupMembersList.vue'
|
||||||
|
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
|
||||||
|
import useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js'
|
||||||
|
import { ref, computed, reactive } from 'vue'
|
||||||
|
import { useDialogueStore } from '@/store'
|
||||||
|
|
||||||
|
const dialogueStore = useDialogueStore()
|
||||||
|
const talkParams = reactive({
|
||||||
|
memberList: computed(() => dialogueStore.members),
|
||||||
|
})
|
||||||
|
|
||||||
|
const zPaging = ref()
|
||||||
|
useZPaging(zPaging)
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.outer-layer {
|
||||||
|
flex: 1;
|
||||||
|
background-image: url('@/static/image/clockIn/z3280@3x.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
.group-members-list {
|
||||||
|
margin: 20rpx 32rpx;
|
||||||
|
padding: 0 0 32rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
129
src/pages/chatSettings/groupManage/manageGroupSilence.vue
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<template>
|
||||||
|
<div class="outer-layer manage-group-silence-page">
|
||||||
|
<div class="root">
|
||||||
|
<ZPaging ref="zPaging" :show-scrollbar="false">
|
||||||
|
<template #top>
|
||||||
|
<tm-navbar :hideBack="false" hideHome title="" :leftWidth="220">
|
||||||
|
<div class="navBar-title flex flex-col items-center justify-center">
|
||||||
|
<span class="text-[34rpx] font-medium">
|
||||||
|
{{ $t('chat.settings.groupGag') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</tm-navbar>
|
||||||
|
</template>
|
||||||
|
<div class="manage-group-silence">
|
||||||
|
<span class="manage-group-silence-title text-[28rpx] font-regular">
|
||||||
|
{{ $t('chat.manage.silenceMember') }}
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="add-silence-member-btn chat-settings-card"
|
||||||
|
@click="toSelectMembersPage"
|
||||||
|
>
|
||||||
|
<img src="/src/static/image/chatSettings/add-btn.png" />
|
||||||
|
<span class="text-[28rpx] font-medium">
|
||||||
|
{{ $t('chat.manage.addSilenceMember') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="silence-all-btn chat-settings-card">
|
||||||
|
<settingFormItem
|
||||||
|
:item="state.silenceAllBtn"
|
||||||
|
:sessionInfo="state?.sessionInfo"
|
||||||
|
@changeSwitch="changeSwitch"
|
||||||
|
></settingFormItem>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ZPaging>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import settingFormItem from '../components/settingFormItem.vue'
|
||||||
|
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { computed, onMounted, reactive } from 'vue'
|
||||||
|
|
||||||
|
import { useGroupStore, useDialogueStore } from '@/store'
|
||||||
|
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const groupStore = useGroupStore()
|
||||||
|
const dialogueStore = useDialogueStore()
|
||||||
|
|
||||||
|
const dialogueParams = reactive({
|
||||||
|
silenceMembersList: computed(() => dialogueStore.getAdminList),
|
||||||
|
})
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
silenceAllBtn: null, //全员禁言按钮
|
||||||
|
})
|
||||||
|
|
||||||
|
onLoad((options) => {
|
||||||
|
console.log(options)
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
console.log(dialogueParams.silenceMembersList)
|
||||||
|
state.silenceAllBtn = {
|
||||||
|
label: t('chat.manage.silenceAll'),
|
||||||
|
hasPointer: false,
|
||||||
|
value: '',
|
||||||
|
subValue: t('chat.manage.silenceAllHint'),
|
||||||
|
customInfo: 'switch',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//切换开关选择
|
||||||
|
const changeSwitch = (switchStatus, label) => {
|
||||||
|
console.log(switchStatus, label)
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击跳转到添加禁言成员页面
|
||||||
|
const toSelectMembersPage = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/chatSettings/groupManage/selectMembers?manageType=silence',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.outer-layer {
|
||||||
|
flex: 1;
|
||||||
|
background-image: url('@/static/image/clockIn/z3280@3x.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manage-group-silence {
|
||||||
|
padding: 20rpx 32rpx;
|
||||||
|
.manage-group-silence-title {
|
||||||
|
line-height: 40rpx;
|
||||||
|
color: #959598;
|
||||||
|
}
|
||||||
|
.add-silence-member-btn {
|
||||||
|
padding: 32rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
img {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
margin: 0 22rpx 0 0;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
line-height: 40rpx;
|
||||||
|
color: $theme-text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.silence-all-btn {
|
||||||
|
padding: 32rpx;
|
||||||
|
}
|
||||||
|
.chat-settings-card {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx 0 0;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
box-shadow: 0 6px 12px 2px rgba(188, 188, 188, 0.08);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
141
src/pages/chatSettings/groupManage/manageNotice.vue
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
<template>
|
||||||
|
<div class="outer-layer manage-notice-page">
|
||||||
|
<div class="root">
|
||||||
|
<ZPaging ref="zPaging" :show-scrollbar="false">
|
||||||
|
<template #top>
|
||||||
|
<tm-navbar :hideBack="true" hideHome title="" :leftWidth="220">
|
||||||
|
<template #left>
|
||||||
|
<div class="nav-bar-cancel-btn">
|
||||||
|
<span class="text-[34rpx] font-regular" @click="toPrevPage">
|
||||||
|
{{ $t('cancel') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="navBar-title flex flex-col items-center justify-center">
|
||||||
|
<span class="text-[34rpx] font-medium">
|
||||||
|
{{ $t('chat.settings.groupNotice') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<template #right>
|
||||||
|
<div
|
||||||
|
class="nav-bar-done-btn"
|
||||||
|
:class="state.canDoComplete ? 'nav-bar-done-btn-can-do' : ''"
|
||||||
|
>
|
||||||
|
<span class="text-[34rpx] font-regular">
|
||||||
|
{{ $t('button.text.done') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</tm-navbar>
|
||||||
|
</template>
|
||||||
|
<div class="notice-text-area">
|
||||||
|
<wd-textarea
|
||||||
|
style="height: 100%;"
|
||||||
|
v-model="state.groupNotice"
|
||||||
|
:placeholder="$t('input.placeholder.enter')"
|
||||||
|
:maxlength="500"
|
||||||
|
:show-word-limit="true"
|
||||||
|
@input="inputGroupNotice"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</ZPaging>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
groupNotice: '', //群公告
|
||||||
|
canDoComplete: false, //是否可以点击完成按钮
|
||||||
|
})
|
||||||
|
|
||||||
|
//点击返回上一页
|
||||||
|
const toPrevPage = () => {
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//输入群公告
|
||||||
|
const inputGroupNotice = (e) => {
|
||||||
|
state.groupNotice = e
|
||||||
|
if (e.trim()) {
|
||||||
|
state.canDoComplete = true
|
||||||
|
} else {
|
||||||
|
state.canDoComplete = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.outer-layer {
|
||||||
|
flex: 1;
|
||||||
|
background-image: url('@/static/image/clockIn/z3280@3x.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manage-notice-page {
|
||||||
|
::v-deep .zp-paging-container-content {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.nav-bar-cancel-btn {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 0 0 42rpx;
|
||||||
|
span {
|
||||||
|
line-height: 40rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.nav-bar-done-btn {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 36rpx 0 0;
|
||||||
|
padding: 6rpx 24rpx;
|
||||||
|
background-color: #f3f3f3;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
span {
|
||||||
|
color: #bababa;
|
||||||
|
line-height: 40rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-bar-done-btn-can-do {
|
||||||
|
background-color: $theme-primary;
|
||||||
|
span {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notice-text-area {
|
||||||
|
padding: 20rpx 32rpx;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
::v-deep .wd-textarea {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .wd-textarea__value {
|
||||||
|
padding-right: 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .wd-textarea__inner {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .uni-textarea-compute {
|
||||||
|
div {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 44rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
401
src/pages/chatSettings/groupManage/selectMembers.vue
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
<template>
|
||||||
|
<div class="outer-layer select-members-page">
|
||||||
|
<div class="root">
|
||||||
|
<ZPaging
|
||||||
|
ref="zPaging"
|
||||||
|
:show-scrollbar="false"
|
||||||
|
:use-virtual-list="true"
|
||||||
|
:virtual-list-col="5"
|
||||||
|
:refresher-enabled="false"
|
||||||
|
:loading-more-enabled="false"
|
||||||
|
@scroll="onScroll"
|
||||||
|
>
|
||||||
|
<template #top>
|
||||||
|
<tm-navbar
|
||||||
|
:hideBack="false"
|
||||||
|
hideHome
|
||||||
|
title=""
|
||||||
|
:leftWidth="220"
|
||||||
|
id="topArea"
|
||||||
|
>
|
||||||
|
<div class="navBar-title flex flex-col items-center justify-center">
|
||||||
|
<span
|
||||||
|
class="text-[34rpx] font-medium"
|
||||||
|
v-if="state.manageType === 'silence'"
|
||||||
|
>
|
||||||
|
{{ $t('chat.manage.addSilenceMember') }}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="text-[34rpx] font-medium"
|
||||||
|
v-if="state.manageType === 'admin'"
|
||||||
|
>
|
||||||
|
{{ $t('chat.manage.addAdmin') }}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="text-[34rpx] font-medium"
|
||||||
|
v-if="state.manageType === 'searchRecord'"
|
||||||
|
>
|
||||||
|
{{ $t('search.condition.member') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</tm-navbar>
|
||||||
|
</template>
|
||||||
|
<div class="select-members">
|
||||||
|
<div class="search-member">
|
||||||
|
<customInput
|
||||||
|
:searchText="state.searchText"
|
||||||
|
@inputSearchText="inputSearchText"
|
||||||
|
></customInput>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="member-list"
|
||||||
|
:style="{
|
||||||
|
padding: state.manageType === 'searchRecord' ? '20rpx 0 0' : '',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div class="member-list-alphabet-anchor-point">
|
||||||
|
<div
|
||||||
|
class="member-list-alphabet-anchor-point-each"
|
||||||
|
v-for="(alphabetItem, alphabetIndex) in state?.alphabet"
|
||||||
|
:key="alphabetIndex"
|
||||||
|
:style="{
|
||||||
|
margin: state?.alphabet?.length > 17 ? '0' : '',
|
||||||
|
}"
|
||||||
|
@click.stop="scrollToView(alphabetItem)"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="text-[32rpx] font-regular"
|
||||||
|
:style="{
|
||||||
|
color:
|
||||||
|
state.currentAlphabet === alphabetItem ? '#7A58DE' : '',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ alphabetItem }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="member-list-alphabet"
|
||||||
|
v-for="(alphabetItem, alphabetIndex) in state.resultMemberList"
|
||||||
|
:key="alphabetIndex"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="member-list-alphabet-key"
|
||||||
|
:style="{
|
||||||
|
padding:
|
||||||
|
state.manageType === 'searchRecord' ? '10rpx 30rpx' : '',
|
||||||
|
}"
|
||||||
|
v-if="alphabetItem?.memberList?.length > 0"
|
||||||
|
:id="alphabetItem.key"
|
||||||
|
:ref="
|
||||||
|
(el) => {
|
||||||
|
if (el) alphabetElementRefs[alphabetIndex] = el
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<span class="text-[32rpx] font-regular">
|
||||||
|
{{ alphabetItem.key }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="alphabetItem?.memberList?.length > 0">
|
||||||
|
<div
|
||||||
|
class="member-list-each"
|
||||||
|
v-for="(item, index) in alphabetItem?.memberList"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<tm-checkbox-group v-model="item.checkArr">
|
||||||
|
<selectMemberItem
|
||||||
|
:memberItem="item"
|
||||||
|
@clickItem="handleClickItem(item)"
|
||||||
|
:manageType="state.manageType"
|
||||||
|
:itemStyle="
|
||||||
|
state.manageType === 'searchRecord' ? 'list' : 'card'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
#left
|
||||||
|
v-if="state.manageType !== 'searchRecord'"
|
||||||
|
>
|
||||||
|
<tm-checkbox
|
||||||
|
:round="10"
|
||||||
|
color="#46299d"
|
||||||
|
:value="item.id"
|
||||||
|
:disabled="item.is_mute === 1"
|
||||||
|
></tm-checkbox>
|
||||||
|
</template>
|
||||||
|
</selectMemberItem>
|
||||||
|
</tm-checkbox-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template #bottom v-if="state.manageType !== 'searchRecord'">
|
||||||
|
<customBtn
|
||||||
|
:isBottom="true"
|
||||||
|
:btnText="$t('ok')"
|
||||||
|
@clickBtn="confirmSilenceMember"
|
||||||
|
></customBtn>
|
||||||
|
</template>
|
||||||
|
</ZPaging>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import customInput from '@/components/custom-input/custom-input.vue'
|
||||||
|
import selectMemberItem from '../components/select-member-item.vue'
|
||||||
|
import customBtn from '@/components/custom-btn/custom-btn.vue'
|
||||||
|
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
|
||||||
|
import useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js'
|
||||||
|
import { computed, onMounted, reactive, ref, watch, nextTick } from 'vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
|
||||||
|
import { useDialogueStore } from '@/store'
|
||||||
|
|
||||||
|
const zPaging = ref()
|
||||||
|
useZPaging(zPaging)
|
||||||
|
|
||||||
|
const dialogueStore = useDialogueStore()
|
||||||
|
const state = reactive({
|
||||||
|
searchText: '', //搜索内容
|
||||||
|
manageType: '', //管理类型
|
||||||
|
alphabet: [], //A-Z列表
|
||||||
|
resultMemberList: [], //按A-Z整理后的人员列表
|
||||||
|
currentAlphabet: 'A', //当前A-Z位置
|
||||||
|
scrollDirection: '', //当前列表滚动方向
|
||||||
|
isAssign: false, //是否指定view
|
||||||
|
})
|
||||||
|
const dialogueParams = reactive({
|
||||||
|
memberList: computed(() => {
|
||||||
|
const lowerCaseSearchText = state?.searchText.toLowerCase()
|
||||||
|
return dialogueStore.members.filter((item) =>
|
||||||
|
state?.searchText
|
||||||
|
? item.nickname.toLowerCase().includes(lowerCaseSearchText)
|
||||||
|
: true,
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
receiverId: computed(() => dialogueStore.talk.receiver_id),
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => dialogueParams?.memberList,
|
||||||
|
(newMemberList) => {
|
||||||
|
assembleAlphabetMmeberList(newMemberList)
|
||||||
|
},
|
||||||
|
{ deep: true },
|
||||||
|
)
|
||||||
|
|
||||||
|
//获取A-Z tag元素
|
||||||
|
const alphabetElementRefs = ref([])
|
||||||
|
//观察者
|
||||||
|
let observer
|
||||||
|
|
||||||
|
onLoad((options) => {
|
||||||
|
console.log(options)
|
||||||
|
if (options.manageType) {
|
||||||
|
state.manageType = options.manageType
|
||||||
|
assembleAlphabetMmeberList(dialogueParams?.memberList)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
dialogueParams.memberList.forEach((ele) => {
|
||||||
|
ele.checkArr = []
|
||||||
|
})
|
||||||
|
const options = {
|
||||||
|
root: null, // 使用浏览器窗口作为根容器
|
||||||
|
threshold: 1.0, // 当元素100%离开视口时触发
|
||||||
|
}
|
||||||
|
observer = new IntersectionObserver(handleIntersection, options)
|
||||||
|
nextTick(() => {
|
||||||
|
watch(
|
||||||
|
alphabetElementRefs,
|
||||||
|
(newAlphabetElementRefs) => {
|
||||||
|
if (Array.isArray(newAlphabetElementRefs)) {
|
||||||
|
newAlphabetElementRefs.forEach((el, index) => {
|
||||||
|
observeElement(el, index)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: true },
|
||||||
|
)
|
||||||
|
if (alphabetElementRefs.value.length > 0) {
|
||||||
|
alphabetElementRefs.value.forEach((el, index) =>
|
||||||
|
observeElement(el, index),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 观察者函数
|
||||||
|
const handleIntersection = (entries) => {
|
||||||
|
if (state.isAssign) {
|
||||||
|
state.isAssign = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
entries.forEach((entry) => {
|
||||||
|
if (!entry.isIntersecting && state.scrollDirection === 'down') {
|
||||||
|
state.currentAlphabet = entry.target.id
|
||||||
|
} else if (entry.isIntersecting && state.scrollDirection === 'up') {
|
||||||
|
if (state?.alphabet?.length > 1) {
|
||||||
|
state?.alphabet.forEach((item, index) => {
|
||||||
|
if (item === entry.target.id && index > 0) {
|
||||||
|
state.currentAlphabet = state?.alphabet[index - 1]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
state.currentAlphabet = entry.target.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//观察元素
|
||||||
|
const observeElement = (el, index) => {
|
||||||
|
if (el && observer) {
|
||||||
|
observer.observe(el)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//输入搜索文本
|
||||||
|
const inputSearchText = (e) => {
|
||||||
|
// console.log(e)
|
||||||
|
state.searchText = e
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击item
|
||||||
|
const handleClickItem = (item) => {
|
||||||
|
dialogueParams.memberList.forEach((ele) => {
|
||||||
|
if (ele.id == item.id) {
|
||||||
|
ele.checkArr = ele.checkArr?.length > 0 ? [] : [item.id]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击确认要禁言的成员
|
||||||
|
const confirmSilenceMember = () => {
|
||||||
|
let selectedUserIds = ''
|
||||||
|
dialogueParams.memberList.forEach((ele) => {
|
||||||
|
if (ele.checkArr?.length > 0) {
|
||||||
|
if (!selectedUserIds) {
|
||||||
|
selectedUserIds = ele.checkArr[0]
|
||||||
|
} else {
|
||||||
|
selectedUserIds += ',' + ele.checkArr[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log(selectedUserIds)
|
||||||
|
if (selectedUserIds) {
|
||||||
|
let params = {
|
||||||
|
mode: 1, //1禁言2解禁
|
||||||
|
group_id: dialogueParams.receiverId, //群id
|
||||||
|
user_ids: selectedUserIds, //用户ids
|
||||||
|
}
|
||||||
|
console.log(params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//组装A-Z排序的人员列表
|
||||||
|
const assembleAlphabetMmeberList = (newMemberList) => {
|
||||||
|
if (state.manageType === 'searchRecord') {
|
||||||
|
const resultMemberList = ref([])
|
||||||
|
const alphabet = Array.from({ length: 26 }, (_, i) =>
|
||||||
|
String.fromCharCode(i + 65),
|
||||||
|
)
|
||||||
|
let tempAlphabet = []
|
||||||
|
alphabet.forEach((letter) => {
|
||||||
|
const matchedItems = newMemberList.filter((item) => item.key === letter)
|
||||||
|
if (matchedItems.length > 0) {
|
||||||
|
tempAlphabet.push(letter)
|
||||||
|
}
|
||||||
|
resultMemberList.value.push({
|
||||||
|
key: letter,
|
||||||
|
memberList: matchedItems.length ? matchedItems : [],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
state.alphabet = tempAlphabet
|
||||||
|
state.resultMemberList = resultMemberList
|
||||||
|
} else {
|
||||||
|
state.resultMemberList = [
|
||||||
|
{
|
||||||
|
key: '',
|
||||||
|
memberList: newMemberList,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//滚动到指定的view
|
||||||
|
const scrollToView = (alphabet) => {
|
||||||
|
state.currentAlphabet = alphabet
|
||||||
|
state.isAssign = true
|
||||||
|
console.log()
|
||||||
|
zPaging.value?.scrollIntoViewById(
|
||||||
|
alphabet,
|
||||||
|
document.getElementById('topArea').clientHeight
|
||||||
|
? document.getElementById('topArea').clientHeight - 1
|
||||||
|
: 80,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
//监听列表滚动
|
||||||
|
const onScroll = (e) => {
|
||||||
|
if (e.detail.deltaY < 0) {
|
||||||
|
state.scrollDirection = 'down'
|
||||||
|
} else if (e.detail.deltaY > 0) {
|
||||||
|
state.scrollDirection = 'up'
|
||||||
|
} else {
|
||||||
|
state.scrollDirection = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.outer-layer {
|
||||||
|
flex: 1;
|
||||||
|
background-image: url('@/static/image/clockIn/z3280@3x.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-members {
|
||||||
|
padding: 20rpx 32rpx;
|
||||||
|
.search-member {
|
||||||
|
padding: 22rpx 16rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
.member-list {
|
||||||
|
.member-list-alphabet-anchor-point {
|
||||||
|
position: fixed;
|
||||||
|
right: 32rpx;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
.member-list-alphabet-anchor-point-each {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 0 14rpx;
|
||||||
|
span {
|
||||||
|
width: 52rpx;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 44rpx;
|
||||||
|
color: $theme-text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.member-list-alphabet {
|
||||||
|
.member-list-alphabet-key {
|
||||||
|
background-color: #f3f3f3;
|
||||||
|
span {
|
||||||
|
line-height: 44rpx;
|
||||||
|
color: $theme-text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
639
src/pages/chatSettings/index.vue
Normal file
@ -0,0 +1,639 @@
|
|||||||
|
<template>
|
||||||
|
<div class="outer-layer chat-settings-page">
|
||||||
|
<div class="root">
|
||||||
|
<ZPaging ref="zPaging" :show-scrollbar="false">
|
||||||
|
<template #top>
|
||||||
|
<tm-navbar :hideBack="false" hideHome title="" :leftWidth="220">
|
||||||
|
<div class="navBar-title flex flex-col items-center justify-center">
|
||||||
|
<span class="text-[34rpx] font-medium">
|
||||||
|
{{ $t('index.chat.settings') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</tm-navbar>
|
||||||
|
</template>
|
||||||
|
<div class="chat-settings">
|
||||||
|
<div class="chat-group-base-infos chat-settings-card">
|
||||||
|
<div class="base-info-avatar" @click="toEditAvatarPage">
|
||||||
|
<img :src="groupAvatar" />
|
||||||
|
</div>
|
||||||
|
<div class="base-info">
|
||||||
|
<div class="base-info-name">
|
||||||
|
<span class="text-[32rpx] font-medium">{{ groupName }}</span>
|
||||||
|
<span class="base-info_num text-[32rpx] font-medium">
|
||||||
|
{{ '(' + groupNum + ')' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="base-info-tag"
|
||||||
|
:style="{
|
||||||
|
borderColor:
|
||||||
|
groupTypeMapping[groupParams?.groupInfo?.group_type]
|
||||||
|
?.result_type_color,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="text-[24rpx] font-medium"
|
||||||
|
:style="{
|
||||||
|
color:
|
||||||
|
groupTypeMapping[groupParams?.groupInfo?.group_type]
|
||||||
|
?.result_type_color,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ groupType }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="base-info-edit" @click="toEditGroupInfoPage">
|
||||||
|
<img src="/src/static/image/chatSettings/edit-btn.png" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chat-group-members chat-group-infos chat-settings-card">
|
||||||
|
<div
|
||||||
|
class="chat-group-infos-each"
|
||||||
|
v-for="(item, index) in state.chatGroupMembers"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<settingFormItem
|
||||||
|
:item="item"
|
||||||
|
@toManagePage="toManagePage"
|
||||||
|
></settingFormItem>
|
||||||
|
<groupMemberList
|
||||||
|
:memberList="dialogueParams?.memberList"
|
||||||
|
:memberListsLimit="15"
|
||||||
|
></groupMemberList>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chat-group-infos chat-settings-card">
|
||||||
|
<div
|
||||||
|
class="chat-group-infos-each"
|
||||||
|
v-for="(item, index) in state.chatGroupInfos"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<settingFormItem
|
||||||
|
:item="item"
|
||||||
|
@toManagePage="toManagePage"
|
||||||
|
></settingFormItem>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chat-records-search chat-settings-card">
|
||||||
|
<customInput></customInput>
|
||||||
|
<div class="record-search-types">
|
||||||
|
<div
|
||||||
|
class="record-search-types-each"
|
||||||
|
v-for="(item, index) in state.recordSearchTypeList"
|
||||||
|
:key="index"
|
||||||
|
@click="toSearchByConditionPage(index)"
|
||||||
|
>
|
||||||
|
<img class="record-search-types-icon" :src="item.typeIcon" />
|
||||||
|
<span class="text-[24rpx] font-regular">{{ item.value }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chat-group-infos chat-settings-card">
|
||||||
|
<div
|
||||||
|
class="chat-group-infos-each"
|
||||||
|
v-for="(item, index) in state.chatSettings"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<settingFormItem
|
||||||
|
:item="item"
|
||||||
|
@toManagePage="toManagePage"
|
||||||
|
:sessionInfo="state?.sessionInfo"
|
||||||
|
@changeSwitch="changeSwitch"
|
||||||
|
></settingFormItem>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chat-group-infos chat-settings-card">
|
||||||
|
<div
|
||||||
|
class="chat-group-infos-each"
|
||||||
|
v-for="(item, index) in state.chatManagement"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<settingFormItem
|
||||||
|
:item="item"
|
||||||
|
@toManagePage="toManagePage"
|
||||||
|
></settingFormItem>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="clear-chat-record-btn chat-settings-card">
|
||||||
|
<div class="clear-chat-record-btn-each">
|
||||||
|
<span class="text-[32rpx] font-regular">
|
||||||
|
{{ $t('chat.settings.clearChatRecord') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="clear-chat-record-btn-each">
|
||||||
|
<span class="text-[32rpx] font-regular">
|
||||||
|
{{ $t('group.disband.btn') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="clear-chat-record-btn-each">
|
||||||
|
<span class="text-[32rpx] font-regular">
|
||||||
|
{{ $t('group.quit.btn') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ZPaging>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import zu4992 from '@/static/image/chatList/zu4992@2x.png'
|
||||||
|
import zu4991 from '@/static/image/chatList/zu4991@2x.png'
|
||||||
|
import zu4989 from '@/static/image/chatList/zu4989@2x.png'
|
||||||
|
import zu5296 from '@/static/image/chatList/zu5296@2x.png'
|
||||||
|
import recordSearchTypeIcon_groupMember from '@/static/image/chatSettings/recordSearchTypeGroupMembers.png'
|
||||||
|
import recordSearchTypeIcon_date from '@/static/image/chatSettings/recordSearchTypeDate.png'
|
||||||
|
import recordSearchTypeIcon_imgAndVideo from '@/static/image/chatSettings/recordSearchTypeImgAndVideo.png'
|
||||||
|
import recordSearchTypeIcon_files from '@/static/image/chatSettings/recordSearchTypeFiles.png'
|
||||||
|
import recordSearchTypeIcon_link from '@/static/image/chatSettings/recordSearchTypeLink.png'
|
||||||
|
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
|
||||||
|
import settingFormItem from './components/settingFormItem.vue'
|
||||||
|
import groupMemberList from './components/groupMembersList.vue'
|
||||||
|
import { computed, onMounted, reactive } from 'vue'
|
||||||
|
import {
|
||||||
|
useUserStore,
|
||||||
|
useTalkStore,
|
||||||
|
useDialogueStore,
|
||||||
|
useGroupStore,
|
||||||
|
} from '@/store'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { ServeTopTalkList, ServeSetNotDisturb } from '@/api/chat/index'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
const { t } = useI18n()
|
||||||
|
import customInput from '@/components/custom-input/custom-input.vue'
|
||||||
|
const userStore = useUserStore()
|
||||||
|
const talkStore = useTalkStore()
|
||||||
|
const dialogueStore = useDialogueStore()
|
||||||
|
const dialogueParams = reactive({
|
||||||
|
uid: computed(() => userStore.uid),
|
||||||
|
index_name: computed(() => dialogueStore.index_name),
|
||||||
|
type: computed(() => dialogueStore.talk.talk_type),
|
||||||
|
receiver_id: computed(() => dialogueStore.talk.receiver_id),
|
||||||
|
username: computed(() => dialogueStore.talk.username),
|
||||||
|
online: computed(() => dialogueStore.online),
|
||||||
|
keyboard: computed(() => dialogueStore.keyboard),
|
||||||
|
num: computed(() => dialogueStore.members.length),
|
||||||
|
memberList: computed(() => dialogueStore.members),
|
||||||
|
})
|
||||||
|
const talkParams = reactive({
|
||||||
|
topItems: computed(() => talkStore.topItems),
|
||||||
|
disturbItems: computed(() => talkStore.disturbItems),
|
||||||
|
})
|
||||||
|
const groupStore = useGroupStore()
|
||||||
|
const groupParams = reactive({
|
||||||
|
groupInfo: computed(() => groupStore.groupInfo),
|
||||||
|
groupNotice: computed(() => groupStore.groupNotice),
|
||||||
|
})
|
||||||
|
const state = reactive({
|
||||||
|
chatGroupMembers: [], //群成员form-item
|
||||||
|
chatGroupInfos: [], //群聊信息
|
||||||
|
recordSearchTypeList: [], //聊天记录搜索类型
|
||||||
|
chatSettings: [], //群聊设置
|
||||||
|
chatManagement: [], //群聊管理
|
||||||
|
groupId: '', //群id
|
||||||
|
sessionId: '', //会话id
|
||||||
|
})
|
||||||
|
|
||||||
|
onLoad(async (options) => {
|
||||||
|
console.log(dialogueParams)
|
||||||
|
if (options.groupId) {
|
||||||
|
console.log(options.groupId)
|
||||||
|
state.groupId = Number(options.groupId)
|
||||||
|
await groupStore.ServeGroupDetail()
|
||||||
|
await groupStore.ServeGetGroupNotices()
|
||||||
|
updateGroupInfos()
|
||||||
|
}
|
||||||
|
if (options.sessionId) {
|
||||||
|
state.sessionId = Number(options.sessionId)
|
||||||
|
if (talkParams.topItems.length > 0) {
|
||||||
|
talkParams.topItems.forEach((item) => {
|
||||||
|
if (item.id == options.sessionId) {
|
||||||
|
state.sessionInfo = item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (talkParams.disturbItems.length > 0) {
|
||||||
|
talkParams.disturbItems.forEach((item) => {
|
||||||
|
if (item.id == options.sessionId) {
|
||||||
|
state.sessionInfo = item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
updateGroupInfos()
|
||||||
|
state.recordSearchTypeList = [
|
||||||
|
{
|
||||||
|
value: t('chat.settings.groupMember'),
|
||||||
|
typeIcon: recordSearchTypeIcon_groupMember,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: t('record.searchType.date'),
|
||||||
|
typeIcon: recordSearchTypeIcon_date,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: t('record.searchType.imgAndVideo'),
|
||||||
|
typeIcon: recordSearchTypeIcon_imgAndVideo,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: t('record.searchType.files'),
|
||||||
|
typeIcon: recordSearchTypeIcon_files,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: t('record.searchType.link'),
|
||||||
|
typeIcon: recordSearchTypeIcon_link,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
state.chatSettings = [
|
||||||
|
{
|
||||||
|
label: t('chat.settings.topSession'),
|
||||||
|
hasPointer: false,
|
||||||
|
value: '',
|
||||||
|
subValue: '',
|
||||||
|
customInfo: 'switch',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('chat.settings.messageNoDisturb'),
|
||||||
|
hasPointer: false,
|
||||||
|
value: '',
|
||||||
|
subValue: '',
|
||||||
|
customInfo: 'switch',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
state.chatManagement = [
|
||||||
|
{
|
||||||
|
label: t('chat.settings.groupGag'),
|
||||||
|
hasPointer: true,
|
||||||
|
value: '',
|
||||||
|
subValue: '',
|
||||||
|
customInfo: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('chat.settings.groupAdmin'),
|
||||||
|
hasPointer: true,
|
||||||
|
value: '',
|
||||||
|
subValue: '总经理室-总经理,苏州站-出纳,常熟站…',
|
||||||
|
customInfo: '',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
//群头像
|
||||||
|
const groupAvatar = computed(() => {
|
||||||
|
return (
|
||||||
|
groupParams?.groupInfo?.avatar ||
|
||||||
|
groupTypeMapping[groupParams?.groupInfo?.group_type]?.defaultImg
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
//群名称
|
||||||
|
const groupName = computed(() => {
|
||||||
|
return groupParams?.groupInfo?.group_name
|
||||||
|
})
|
||||||
|
|
||||||
|
//群人数
|
||||||
|
const groupNum = computed(() => {
|
||||||
|
return groupParams?.groupInfo?.group_num || 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 映射表-根据groupType设置对应值
|
||||||
|
const groupTypeMapping = {
|
||||||
|
0: {
|
||||||
|
defaultImg: 'textImg',
|
||||||
|
},
|
||||||
|
1: {
|
||||||
|
defaultImg: zu4992,
|
||||||
|
},
|
||||||
|
2: {
|
||||||
|
result_type: t('index.mine.department'),
|
||||||
|
result_type_color: '#377EC6',
|
||||||
|
defaultImg: zu4989,
|
||||||
|
},
|
||||||
|
3: {
|
||||||
|
result_type: t('index.mine.project'),
|
||||||
|
result_type_color: '#C1681C',
|
||||||
|
defaultImg: zu4991,
|
||||||
|
},
|
||||||
|
4: {
|
||||||
|
result_type: t('index.type.company'),
|
||||||
|
result_type_color: '#7A58DE',
|
||||||
|
defaultImg: zu5296,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
//群类型
|
||||||
|
const groupType = computed(() => {
|
||||||
|
return groupTypeMapping[groupParams?.groupInfo?.group_type]?.result_type || ''
|
||||||
|
})
|
||||||
|
|
||||||
|
//更新群信息
|
||||||
|
const updateGroupInfos = () => {
|
||||||
|
state.chatGroupMembers = [
|
||||||
|
{
|
||||||
|
label: t('chat.settings.groupMember'),
|
||||||
|
hasPointer: true,
|
||||||
|
value: '全部(' + groupNum.value + ')',
|
||||||
|
subValue: '',
|
||||||
|
customInfo: '',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
state.chatGroupInfos = [
|
||||||
|
{
|
||||||
|
label: t('chat.settings.groupName'),
|
||||||
|
hasPointer: true,
|
||||||
|
value: groupName.value,
|
||||||
|
subValue: '',
|
||||||
|
customInfo: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('chat.settings.groupNotice'),
|
||||||
|
hasPointer: true,
|
||||||
|
value: '',
|
||||||
|
subValue: groupParams.groupNotice[0],
|
||||||
|
customInfo: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('chat.settings.groupType'),
|
||||||
|
hasPointer: false,
|
||||||
|
value: groupType.value + '群',
|
||||||
|
subValue: '',
|
||||||
|
customInfo: '',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击跳转到修改群信息页面
|
||||||
|
const toEditGroupInfoPage = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url:
|
||||||
|
'/pages/chatSettings/groupManage/editGroupName?groupAvatar=' +
|
||||||
|
groupAvatar.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击跳转到修改头像页面
|
||||||
|
const toEditAvatarPage = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url:
|
||||||
|
'/pages/chatSettings/groupManage/editAvatar?groupAvatar=' +
|
||||||
|
groupAvatar.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击跳转到管理页面
|
||||||
|
const toManagePage = (label) => {
|
||||||
|
console.log(label)
|
||||||
|
if (label) {
|
||||||
|
if (label === t('chat.settings.groupName')) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url:
|
||||||
|
'/pages/chatSettings/groupManage/editGroupName?groupAvatar=' +
|
||||||
|
groupAvatar.value,
|
||||||
|
})
|
||||||
|
} else if (label === t('chat.settings.groupNotice')) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/chatSettings/groupManage/manageNotice',
|
||||||
|
})
|
||||||
|
} else if (label === t('chat.settings.groupMember')) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url:
|
||||||
|
'/pages/chatSettings/groupManage/manageGroupMembers?groupId=' +
|
||||||
|
state.groupId,
|
||||||
|
})
|
||||||
|
} else if (label === t('chat.settings.groupGag')) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/chatSettings/groupManage/manageGroupSilence',
|
||||||
|
})
|
||||||
|
} else if (label === t('chat.settings.groupAdmin')) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/chatSettings/groupManage/manageGroupAdmin',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击跳转到按条件搜索页
|
||||||
|
const toSearchByConditionPage = (flag) => {
|
||||||
|
let condition = ''
|
||||||
|
if (flag == 0) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url:
|
||||||
|
'/pages/chatSettings/groupManage/selectMembers?manageType=searchRecord',
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if (flag == 1) {
|
||||||
|
condition = 'date'
|
||||||
|
}
|
||||||
|
uni.navigateTo({
|
||||||
|
url:
|
||||||
|
'/pages/search/searchByCondition/index?condition=' +
|
||||||
|
condition +
|
||||||
|
'&receiver_id=' +
|
||||||
|
state.groupId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//切换开关选择
|
||||||
|
const changeSwitch = (switchStatus, label) => {
|
||||||
|
let params
|
||||||
|
let resp
|
||||||
|
if (label == t('chat.settings.topSession')) {
|
||||||
|
params = {
|
||||||
|
list_id: state.sessionId, //聊天会话的id
|
||||||
|
type: switchStatus ? 1 : 2,
|
||||||
|
}
|
||||||
|
resp = ServeTopTalkList(params)
|
||||||
|
} else if (label == t('chat.settings.messageNoDisturb')) {
|
||||||
|
params = {
|
||||||
|
talk_type: dialogueParams.type, //1私聊;2群聊
|
||||||
|
receiver_id: dialogueParams.receiver_id, //接收人id或群id
|
||||||
|
is_disturb: switchStatus ? 1 : 0, //是否开启免打扰,0不免打扰,1免打扰
|
||||||
|
}
|
||||||
|
resp = ServeSetNotDisturb(params)
|
||||||
|
}
|
||||||
|
console.log(resp)
|
||||||
|
resp.then(({ code, data }) => {
|
||||||
|
console.log(data)
|
||||||
|
if (code == 200) {
|
||||||
|
if (label == t('chat.settings.topSession')) {
|
||||||
|
talkStore.updateItem({
|
||||||
|
index_name: dialogueParams.index_name,
|
||||||
|
is_top: switchStatus ? 1 : 2,
|
||||||
|
})
|
||||||
|
} else if (label == t('chat.settings.messageNoDisturb')) {
|
||||||
|
talkStore.updateItem({
|
||||||
|
index_name: dialogueParams.index_name,
|
||||||
|
is_disturb: switchStatus ? 1 : 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
resp.catch(() => {})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.outer-layer {
|
||||||
|
flex: 1;
|
||||||
|
background-image: url('@/static/image/clockIn/z3280@3x.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-settings-page {
|
||||||
|
.navBar-title {
|
||||||
|
span {
|
||||||
|
line-height: 48rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-settings {
|
||||||
|
padding: 0 32rpx 36rpx;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.chat-settings-card {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx 0 0;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
box-shadow: 0 6px 12px 2px rgba(188, 188, 188, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-group-base-infos {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 32rpx 40rpx 32rpx 20rpx;
|
||||||
|
|
||||||
|
.base-info-avatar {
|
||||||
|
width: 96rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.base-info {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 30rpx;
|
||||||
|
.base-info-name {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
span {
|
||||||
|
line-height: 44rpx;
|
||||||
|
color: $theme-text;
|
||||||
|
}
|
||||||
|
.base-info_num {
|
||||||
|
line-height: 44rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.base-info-tag {
|
||||||
|
border: 2rpx solid #7a58de;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 2rpx 14rpx;
|
||||||
|
margin: 10rpx 0 0;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
width: 80rpx;
|
||||||
|
span {
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: #7a58de;
|
||||||
|
line-height: 34rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.base-info-edit {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-group-members {
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-group-infos {
|
||||||
|
padding: 0 16rpx;
|
||||||
|
.chat-group-infos-each {
|
||||||
|
padding: 32rpx 14rpx;
|
||||||
|
border-bottom: 1px solid $theme-border-color;
|
||||||
|
}
|
||||||
|
.chat-group-infos-each:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-records-search {
|
||||||
|
padding: 22rpx 16rpx;
|
||||||
|
|
||||||
|
.record-search-types {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
.record-search-types-each {
|
||||||
|
width: calc(100% / 4);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 36rpx 0 0;
|
||||||
|
.record-search-types-icon {
|
||||||
|
width: 106rpx;
|
||||||
|
height: 106rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
line-height: 34px;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-chat-record-btn {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
.clear-chat-record-btn-each {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 32rpx 16rpx;
|
||||||
|
width: calc(100% - 32rpx);
|
||||||
|
border-bottom: 1px solid $theme-border-color;
|
||||||
|
|
||||||
|
span {
|
||||||
|
line-height: 44rpx;
|
||||||
|
color: #cf3050;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.clear-chat-record-btn-each:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<template v-slot:right>
|
<template v-slot:right>
|
||||||
<div class="mr-[36rpx]">
|
<div class="mr-[36rpx]">
|
||||||
<tm-icon color="rgb(51, 51, 51)" :font-size="36" name="tmicon-gengduo"></tm-icon>
|
<tm-icon color="rgb(51, 51, 51)" :font-size="36" name="tmicon-gengduo" @click="toChatSettingsPage"></tm-icon>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</tm-navbar>
|
</tm-navbar>
|
||||||
@ -228,8 +228,7 @@ import zu6053 from "@/static/image/chatList/zu6053@2x.png"
|
|||||||
import deepBubble from "@/components/deep-bubble/deep-bubble.vue"
|
import deepBubble from "@/components/deep-bubble/deep-bubble.vue"
|
||||||
import {isRevoke } from './menu'
|
import {isRevoke } from './menu'
|
||||||
import useConfirm from '@/components/x-confirm/useConfirm.js'
|
import useConfirm from '@/components/x-confirm/useConfirm.js'
|
||||||
|
import { onLoad as uniOnload } from '@dcloudio/uni-app'
|
||||||
|
|
||||||
|
|
||||||
Quill.register('formats/emoji', EmojiBlot)
|
Quill.register('formats/emoji', EmojiBlot)
|
||||||
|
|
||||||
@ -260,6 +259,13 @@ const state = ref({
|
|||||||
isOpenFilePanel: false,
|
isOpenFilePanel: false,
|
||||||
showWin: false,
|
showWin: false,
|
||||||
onfocusItem: null,
|
onfocusItem: null,
|
||||||
|
sessionId: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
uniOnload((options) => {
|
||||||
|
if (options.sessionId) {
|
||||||
|
state.sessionId = options.sessionId
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleEmojiPanel = () => {
|
const handleEmojiPanel = () => {
|
||||||
@ -680,6 +686,13 @@ const initData = async () => {
|
|||||||
zpagingRef.value?.complete(records.value)
|
zpagingRef.value?.complete(records.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//点击跳转到聊天设置页面
|
||||||
|
const toChatSettingsPage = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/chatSettings/index?groupId=' + talkParams?.receiver_id + '&sessionId=' + state.sessionId
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
initData()
|
initData()
|
||||||
})
|
})
|
||||||
|
@ -139,7 +139,7 @@ const cellClick = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: "/pages/dialog/index",
|
url: '/pages/dialog/index?sessionId=' + props.data.id,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
</tm-navbar>
|
</tm-navbar>
|
||||||
</div>
|
</div>
|
||||||
<div class="root">
|
<div class="root">
|
||||||
<div class="searchRoot">
|
<div class="searchRoot" @click="toSearchPage">
|
||||||
<tm-input
|
<tm-input
|
||||||
placeholder="请输入…"
|
placeholder="请输入…"
|
||||||
color="#F9F9FD"
|
color="#F9F9FD"
|
||||||
@ -111,6 +111,12 @@ const creatGroupChat = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toSearchPage = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: "/pages/search/index",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => talkStore,
|
() => talkStore,
|
||||||
(newValue, oldValue) => {
|
(newValue, oldValue) => {
|
||||||
|
70
src/pages/search/components/highLightText.vue
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<template>
|
||||||
|
<span>
|
||||||
|
<template v-for="(part, index) in parts" :key="index">
|
||||||
|
<span v-if="part.highlighted" :class="highlightClass">
|
||||||
|
{{ part.text }}
|
||||||
|
</span>
|
||||||
|
<span v-else>{{ part.text }}</span>
|
||||||
|
</template>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
searchText: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
highlightClass: {
|
||||||
|
type: String,
|
||||||
|
default: 'highlight',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const escapedSearchText = computed(() =>
|
||||||
|
String(props.searchText).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'),
|
||||||
|
)
|
||||||
|
|
||||||
|
const pattern = computed(() => new RegExp(escapedSearchText.value, 'gi'))
|
||||||
|
|
||||||
|
const parts = computed(() => {
|
||||||
|
if (!props.searchText || !props.text)
|
||||||
|
return [{ text: props.text, highlighted: false }];
|
||||||
|
|
||||||
|
const result = [];
|
||||||
|
let currentIndex = 0;
|
||||||
|
const escapedSearchTextValue = escapedSearchText.value;
|
||||||
|
const searchPattern = new RegExp(`(${escapedSearchTextValue})`, 'gi');
|
||||||
|
|
||||||
|
props.text.replace(searchPattern, (match, p1, offset) => {
|
||||||
|
// 添加非高亮文本
|
||||||
|
if (currentIndex < offset) {
|
||||||
|
result.push({ text: props.text.slice(currentIndex, offset), highlighted: false });
|
||||||
|
}
|
||||||
|
// 添加高亮文本
|
||||||
|
result.push({ text: p1, highlighted: true });
|
||||||
|
// 更新当前索引
|
||||||
|
currentIndex = offset + p1.length;
|
||||||
|
return p1; // 这个返回值不影响最终结果,只是replace方法的要求
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加剩余的非高亮文本(如果有的话)
|
||||||
|
if (currentIndex < props.text.length) {
|
||||||
|
result.push({ text: props.text.slice(currentIndex), highlighted: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.highlight {
|
||||||
|
color: #7a58de;
|
||||||
|
}
|
||||||
|
</style>
|
331
src/pages/search/components/searchItem.vue
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="search-item"
|
||||||
|
v-if="resultName"
|
||||||
|
:style="
|
||||||
|
props.searchResultKey === 'talk_record_infos_receiver'
|
||||||
|
? 'margin: 24rpx 0 0'
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="avatar-img">
|
||||||
|
<img v-if="avatarImg !== 'textImg'" :src="avatarImg" />
|
||||||
|
<span v-if="avatarImg === 'textImg'" class="text-[32rpx] font-bold">
|
||||||
|
{{ imgText }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="result-info">
|
||||||
|
<div
|
||||||
|
class="info-name"
|
||||||
|
:class="searchRecordDetail ? 'info-name-searchRecordDetail' : ''"
|
||||||
|
>
|
||||||
|
<HighlightText
|
||||||
|
:class="
|
||||||
|
searchRecordDetail
|
||||||
|
? 'text-[24rpx] font-medium'
|
||||||
|
: 'text-[32rpx] font-medium'
|
||||||
|
"
|
||||||
|
:text="resultName"
|
||||||
|
:searchText="props.searchText"
|
||||||
|
/>
|
||||||
|
<div class="info_num" v-if="groupNum">
|
||||||
|
<span class="text-[32rpx] font-medium">
|
||||||
|
{{ '(' + groupNum + ')' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="info-tag"
|
||||||
|
v-if="resultType && !searchRecordDetail"
|
||||||
|
:style="'border-color:' + resultTypeColor"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="text-[24rpx] font-medium"
|
||||||
|
:style="'color:' + resultTypeColor"
|
||||||
|
>
|
||||||
|
{{ resultType }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="searchRecordDetail && chatRecordCreatedAt">
|
||||||
|
<span class="text-[24rpx] font-medium">
|
||||||
|
{{ chatRecordCreatedAt }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="info-detail"
|
||||||
|
v-if="resultDetail"
|
||||||
|
:class="searchRecordDetail ? 'info-detail-searchRecordDetail' : ''"
|
||||||
|
>
|
||||||
|
<HighlightText
|
||||||
|
class="text-[28rpx] font-regular"
|
||||||
|
:text="resultDetail"
|
||||||
|
:searchText="props.searchText"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="search-item-pointer" v-if="pointerIconSrc">
|
||||||
|
<img :src="pointerIconSrc" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import zu4992 from '@/static/image/chatList/zu4992@2x.png'
|
||||||
|
import zu4991 from '@/static/image/chatList/zu4991@2x.png'
|
||||||
|
import zu4989 from '@/static/image/chatList/zu4989@2x.png'
|
||||||
|
import zu5296 from '@/static/image/chatList/zu5296@2x.png'
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
watch,
|
||||||
|
computed,
|
||||||
|
onMounted,
|
||||||
|
onUnmounted,
|
||||||
|
reactive,
|
||||||
|
defineProps,
|
||||||
|
} from 'vue'
|
||||||
|
import HighlightText from './highLightText.vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { beautifyTime } from '@/utils/datetime'
|
||||||
|
const { t } = useI18n()
|
||||||
|
const props = defineProps({
|
||||||
|
searchItem: Object | Number,
|
||||||
|
searchResultKey: String,
|
||||||
|
searchText: String, //搜索内容
|
||||||
|
searchRecordDetail: Boolean, //是否是搜索聊天记录详情
|
||||||
|
pointerIconSrc: String, //箭头图标
|
||||||
|
})
|
||||||
|
// 映射表-查找对应结构下的属性名
|
||||||
|
const keyMapping = {
|
||||||
|
user_infos: { avatar: 'avatar', name: 'nickname' },
|
||||||
|
group_infos: { avatar: 'avatar', name: 'name', group_num: 'group_num' },
|
||||||
|
group_member_infos: {
|
||||||
|
avatar: 'group_avatar',
|
||||||
|
name: 'group_name',
|
||||||
|
detailKey: 'user_name',
|
||||||
|
group_num: 'group_num',
|
||||||
|
},
|
||||||
|
combinedGroup: {
|
||||||
|
avatar: props.searchItem?.groupTempType
|
||||||
|
? props.searchItem?.groupTempType === 'group_infos'
|
||||||
|
? 'avatar'
|
||||||
|
: props.searchItem?.groupTempType === 'group_member_infos'
|
||||||
|
? 'group_avatar'
|
||||||
|
: ''
|
||||||
|
: '',
|
||||||
|
name: props.searchItem?.groupTempType
|
||||||
|
? props.searchItem?.groupTempType === 'group_infos'
|
||||||
|
? 'name'
|
||||||
|
: props.searchItem?.groupTempType === 'group_member_infos'
|
||||||
|
? 'group_name'
|
||||||
|
: ''
|
||||||
|
: '',
|
||||||
|
detailKey: props.searchItem?.groupTempType
|
||||||
|
? props.searchItem?.groupTempType === 'group_member_infos'
|
||||||
|
? 'user_name'
|
||||||
|
: ''
|
||||||
|
: '',
|
||||||
|
group_num: props.searchItem?.groupTempType
|
||||||
|
? props.searchItem?.groupTempType === 'group_infos'
|
||||||
|
? 'group_num'
|
||||||
|
: props.searchItem?.groupTempType === 'group_member_infos'
|
||||||
|
? 'group_num'
|
||||||
|
: ''
|
||||||
|
: '',
|
||||||
|
},
|
||||||
|
general_infos: {
|
||||||
|
avatar: 'receiver_avatar',
|
||||||
|
name: 'receiver_name',
|
||||||
|
detailKey: 'count',
|
||||||
|
group_num: 'group_num',
|
||||||
|
},
|
||||||
|
talk_record_infos: {
|
||||||
|
avatar: 'user_avatar',
|
||||||
|
name: 'user_name',
|
||||||
|
detailKey: 'extra',
|
||||||
|
created_at: 'created_at',
|
||||||
|
},
|
||||||
|
talk_record_infos_receiver: {
|
||||||
|
avatar: 'receiver_avatar',
|
||||||
|
name: 'receiver_name',
|
||||||
|
group_num: 'group_num',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
//获取key对应值
|
||||||
|
const getKeyValue = (keys) => {
|
||||||
|
let keyValue = ''
|
||||||
|
if (keys) {
|
||||||
|
keyValue = props?.searchItem ? props?.searchItem[keys] : ''
|
||||||
|
}
|
||||||
|
return keyValue
|
||||||
|
}
|
||||||
|
//头像
|
||||||
|
const avatarImg = computed(() => {
|
||||||
|
let avatar = getKeyValue(keyMapping[props.searchResultKey]?.avatar)
|
||||||
|
if (!avatar) {
|
||||||
|
avatar = groupTypeMapping[props.searchItem?.group_type]?.defaultImg
|
||||||
|
}
|
||||||
|
return avatar
|
||||||
|
})
|
||||||
|
//名称
|
||||||
|
const resultName = computed(() => {
|
||||||
|
return getKeyValue(keyMapping[props.searchResultKey]?.name)
|
||||||
|
})
|
||||||
|
//文字头像
|
||||||
|
const imgText = computed(() => {
|
||||||
|
return resultName.value.length >= 2
|
||||||
|
? resultName.value.slice(-2)
|
||||||
|
: resultName.value
|
||||||
|
})
|
||||||
|
// 映射表-根据groupType设置对应值
|
||||||
|
const groupTypeMapping = {
|
||||||
|
0: {
|
||||||
|
defaultImg: 'textImg',
|
||||||
|
},
|
||||||
|
1: {
|
||||||
|
defaultImg: zu4992,
|
||||||
|
},
|
||||||
|
2: {
|
||||||
|
result_type: t('index.mine.department'),
|
||||||
|
result_type_color: '#377EC6',
|
||||||
|
defaultImg: zu4989,
|
||||||
|
},
|
||||||
|
3: {
|
||||||
|
result_type: t('index.mine.project'),
|
||||||
|
result_type_color: '#C1681C',
|
||||||
|
defaultImg: zu4991,
|
||||||
|
},
|
||||||
|
4: {
|
||||||
|
result_type: t('index.type.company'),
|
||||||
|
result_type_color: '#7A58DE',
|
||||||
|
defaultImg: zu5296,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
//群人数
|
||||||
|
const groupNum = computed(() => {
|
||||||
|
return getKeyValue(keyMapping[props.searchResultKey]?.group_num)
|
||||||
|
})
|
||||||
|
//群类型tag
|
||||||
|
const resultType = computed(() => {
|
||||||
|
return groupTypeMapping[props.searchItem?.group_type]?.result_type
|
||||||
|
})
|
||||||
|
//群类型tag颜色
|
||||||
|
const resultTypeColor = computed(() => {
|
||||||
|
return groupTypeMapping[props.searchItem?.group_type]?.result_type_color
|
||||||
|
})
|
||||||
|
//搜索聊天记录详情-时间
|
||||||
|
const chatRecordCreatedAt = computed(() => {
|
||||||
|
let created_at = getKeyValue(keyMapping[props.searchResultKey]?.created_at)
|
||||||
|
return beautifyTime(created_at)
|
||||||
|
})
|
||||||
|
//详细内容
|
||||||
|
const resultDetail = computed(() => {
|
||||||
|
let result_detail =
|
||||||
|
props.searchItem[keyMapping[props.searchResultKey]?.detailKey]
|
||||||
|
switch (keyMapping[props.searchResultKey]?.detailKey) {
|
||||||
|
case 'count':
|
||||||
|
result_detail = result_detail + t('search.chat.count')
|
||||||
|
break
|
||||||
|
case 'user_name':
|
||||||
|
result_detail = t('search.result.include') + result_detail
|
||||||
|
break
|
||||||
|
case 'extra':
|
||||||
|
result_detail = props.searchItem?.extra
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
result_detail = ''
|
||||||
|
}
|
||||||
|
return result_detail
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.search-item:nth-child(1) {
|
||||||
|
border-top: 1px solid $theme-border-color;
|
||||||
|
}
|
||||||
|
.search-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
padding: 22rpx 0 24rpx;
|
||||||
|
border-bottom: 1px solid $theme-border-color;
|
||||||
|
|
||||||
|
.avatar-img {
|
||||||
|
width: 96rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
margin: 0 20rpx 0 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: linear-gradient(to right, #674bbc, #46299d);
|
||||||
|
flex-shrink: 0;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
color: #fff;
|
||||||
|
line-height: 44rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.result-info {
|
||||||
|
width: 100%;
|
||||||
|
.info-name {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
span {
|
||||||
|
color: $theme-text;
|
||||||
|
line-height: 44rpx;
|
||||||
|
}
|
||||||
|
.info-tag {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 2rpx 14rpx;
|
||||||
|
border: 2rpx solid #000;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
span {
|
||||||
|
line-height: 34rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.info-name-searchRecordDetail {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
span {
|
||||||
|
color: $theme-hint-text;
|
||||||
|
line-height: 34rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.info-detail {
|
||||||
|
span {
|
||||||
|
color: $theme-hint-text;
|
||||||
|
line-height: 40rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.info-detail-searchRecordDetail {
|
||||||
|
span {
|
||||||
|
color: $theme-text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.search-item-pointer {
|
||||||
|
width: 11rpx;
|
||||||
|
height: 18rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
419
src/pages/search/components/searchList.vue
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
<template>
|
||||||
|
<div class="search-list">
|
||||||
|
<ZPaging
|
||||||
|
ref="zPaging"
|
||||||
|
:show-scrollbar="false"
|
||||||
|
v-model="state.searchResultList"
|
||||||
|
@query="queryAllSearch"
|
||||||
|
:default-page-no="state.pageNum"
|
||||||
|
:default-page-size="props.searchResultPageSize"
|
||||||
|
:loading-more-default-as-loading="true"
|
||||||
|
:inside-more="true"
|
||||||
|
:empty-view-img="'/src/static//image/search/search-no-data.png'"
|
||||||
|
:empty-view-text="$t('search.hint')"
|
||||||
|
:empty-view-img-style="{ width: '476rpx', height: '261rpx' }"
|
||||||
|
:empty-view-title-style="{
|
||||||
|
color: '#999999',
|
||||||
|
margin: '-20rpx 0 0',
|
||||||
|
'line-height': '40rpx',
|
||||||
|
'font-size': '28rpx',
|
||||||
|
'font-weight': 400,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #top>
|
||||||
|
<div class="searchRoot">
|
||||||
|
<customInput
|
||||||
|
:searchText="state.searchText"
|
||||||
|
:first_talk_record_infos="state.first_talk_record_infos"
|
||||||
|
@inputSearchText="inputSearchText"
|
||||||
|
></customInput>
|
||||||
|
<span
|
||||||
|
class="searchRoot_cancelBtn text-[32rpx] font-medium"
|
||||||
|
@click="cancelSearch"
|
||||||
|
>
|
||||||
|
{{ $t('cancel') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="search-record-detail" v-if="props.searchRecordDetail">
|
||||||
|
<searchItem
|
||||||
|
@click="
|
||||||
|
clickSearchItem(
|
||||||
|
'talk_record_infos_receiver',
|
||||||
|
state?.first_talk_record_infos,
|
||||||
|
)
|
||||||
|
"
|
||||||
|
searchResultKey="talk_record_infos_receiver"
|
||||||
|
:searchItem="state?.first_talk_record_infos"
|
||||||
|
:pointerIconSrc="pointerIconSrc"
|
||||||
|
></searchItem>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="search-result"
|
||||||
|
:style="
|
||||||
|
!state.searchText ? 'align-items:center;justify-content:center;' : ''
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="search-result-list">
|
||||||
|
<div
|
||||||
|
class="search-result-each-part"
|
||||||
|
v-for="(searchResultValue,
|
||||||
|
searchResultKey,
|
||||||
|
searchResultIndex) in state.searchResult"
|
||||||
|
:key="searchResultKey"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="search-result-part"
|
||||||
|
v-if="
|
||||||
|
Array.isArray(state?.searchResult[searchResultKey]) &&
|
||||||
|
state?.searchResult[searchResultKey].length > 0 &&
|
||||||
|
searchResultKey !== 'group_infos' &&
|
||||||
|
searchResultKey !== 'group_member_infos'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="result-title">
|
||||||
|
<span class="text-[28rpx] font-regular">
|
||||||
|
{{ getResultKeysValue(searchResultKey) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="result-list">
|
||||||
|
<div
|
||||||
|
class="result-list-each"
|
||||||
|
v-for="(item, index) in state?.searchResult[searchResultKey]"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<searchItem
|
||||||
|
@click="clickSearchItem(searchResultKey, item)"
|
||||||
|
v-if="(props.listLimit && index < 3) || !props.listLimit"
|
||||||
|
:searchResultKey="searchResultKey"
|
||||||
|
:searchItem="item"
|
||||||
|
:searchText="state.searchText"
|
||||||
|
:searchRecordDetail="props.searchRecordDetail"
|
||||||
|
></searchItem>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="result-has-more"
|
||||||
|
v-if="getHasMoreResult(searchResultKey)"
|
||||||
|
@click="toMoreResultPage(searchResultKey)"
|
||||||
|
>
|
||||||
|
<span class="text-[28rpx] font-regular">
|
||||||
|
{{ getHasMoreResult(searchResultKey) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ZPaging>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import customInput from '@/components/custom-input/custom-input.vue'
|
||||||
|
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
|
||||||
|
import useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js'
|
||||||
|
import searchItem from './searchItem.vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { ref, reactive, defineEmits, defineProps, onMounted } from 'vue'
|
||||||
|
import pointerIconSrc from '@/static/image/search/search-item-pointer.png'
|
||||||
|
|
||||||
|
const zPaging = ref()
|
||||||
|
useZPaging(zPaging)
|
||||||
|
|
||||||
|
const emits = defineEmits([
|
||||||
|
'toMoreResultPage',
|
||||||
|
'lastIdChange',
|
||||||
|
'clickSearchItem',
|
||||||
|
])
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
searchText: '', //搜索内容
|
||||||
|
searchResultList: [], //搜素结果列表
|
||||||
|
searchResult: null, //搜索结果
|
||||||
|
pageNum: 1, //当前请求数据页数
|
||||||
|
})
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
searchResultPageSize: Number, //搜索结果每页数据量
|
||||||
|
listLimit: Boolean, //是否限制列表内数据数量
|
||||||
|
apiParams: String, //请求参数
|
||||||
|
apiRequest: Function, //请求
|
||||||
|
searchText: String, //搜索内容
|
||||||
|
isPagination: Boolean, //是否分页
|
||||||
|
searchRecordDetail: Boolean, //是否是搜索聊天记录的详情
|
||||||
|
first_talk_record_infos: Object, //接受者信息
|
||||||
|
})
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.searchText) {
|
||||||
|
state.searchText = props.searchText
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//输入搜索文本
|
||||||
|
const inputSearchText = (e) => {
|
||||||
|
// console.log(e)
|
||||||
|
if (e.trim() != state.searchText.trim()) {
|
||||||
|
state.pageNum = 1
|
||||||
|
emits('lastIdChange', 0, 0, 0)
|
||||||
|
}
|
||||||
|
state.searchText = e.trim()
|
||||||
|
if (!e.trim()) {
|
||||||
|
emits('lastIdChange', 0, 0, 0)
|
||||||
|
}
|
||||||
|
zPaging.value?.reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ES搜索聊天记录-主页搜索什么都有、指定用户、指定群、群与用户概览
|
||||||
|
const queryAllSearch = (pageNum, searchResultPageSize) => {
|
||||||
|
let params = {
|
||||||
|
key: state.searchText, //关键字
|
||||||
|
size: searchResultPageSize,
|
||||||
|
}
|
||||||
|
if (props.apiParams) {
|
||||||
|
let apiParams = JSON.parse(decodeURIComponent(props.apiParams))
|
||||||
|
params = Object.assign({}, params, apiParams)
|
||||||
|
}
|
||||||
|
const resp = props.apiRequest(params)
|
||||||
|
resp.then(({ code, data }) => {
|
||||||
|
console.log(data)
|
||||||
|
if (code == 200) {
|
||||||
|
if ((data.user_infos || []).length > 0) {
|
||||||
|
;(data.user_infos || []).forEach((item) => {
|
||||||
|
item.group_type = 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if ((data.group_infos || []).length > 0) {
|
||||||
|
;(data.group_infos || []).forEach((item) => {
|
||||||
|
item.group_type = item.type
|
||||||
|
item.groupTempType = 'group_infos'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if ((data.group_member_infos || []).length > 0) {
|
||||||
|
;(data.group_member_infos || []).forEach((item) => {
|
||||||
|
item.groupTempType = 'group_member_infos'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if ((data.talk_record_infos || []).length > 0) {
|
||||||
|
state.first_talk_record_infos = Object.assign(
|
||||||
|
{},
|
||||||
|
state.first_talk_record_infos,
|
||||||
|
data.talk_record_infos[0],
|
||||||
|
)
|
||||||
|
;(data.talk_record_infos || []).forEach((item) => {
|
||||||
|
item.group_type = 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let tempGeneral_infos = Array.isArray(data.general_infos)
|
||||||
|
? [...data.general_infos]
|
||||||
|
: data.general_infos
|
||||||
|
delete data.general_infos
|
||||||
|
data.combinedGroup = (data.group_infos || []).concat(
|
||||||
|
data.group_member_infos || [],
|
||||||
|
)
|
||||||
|
data.general_infos = tempGeneral_infos
|
||||||
|
let isEmpty = true
|
||||||
|
let dataKeys = Object.keys(data)
|
||||||
|
let paginationKey = ''
|
||||||
|
dataKeys.forEach((item) => {
|
||||||
|
if (Array.isArray(data[item]) && data[item].length > 0) {
|
||||||
|
paginationKey = item
|
||||||
|
isEmpty = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (isEmpty) {
|
||||||
|
if (pageNum == 1) {
|
||||||
|
zPaging.value?.complete([])
|
||||||
|
} else {
|
||||||
|
data = state.searchResult
|
||||||
|
zPaging.value?.complete([data])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (props.isPagination) {
|
||||||
|
if (
|
||||||
|
paginationKey &&
|
||||||
|
Array.isArray(
|
||||||
|
(state?.searchResult && state?.searchResult[paginationKey]) || [],
|
||||||
|
) &&
|
||||||
|
((state?.searchResult && state?.searchResult[paginationKey]) || [])
|
||||||
|
.length > 0
|
||||||
|
) {
|
||||||
|
data[paginationKey] = state.searchResult[paginationKey].concat(
|
||||||
|
data[paginationKey],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
emits(
|
||||||
|
'lastIdChange',
|
||||||
|
data.last_id,
|
||||||
|
data.last_group_id,
|
||||||
|
data.last_member_id,
|
||||||
|
)
|
||||||
|
let total = data.count
|
||||||
|
if (props.searchRecordDetail) {
|
||||||
|
total = data.group_record_count
|
||||||
|
}
|
||||||
|
zPaging.value?.completeByTotal([data], total)
|
||||||
|
} else {
|
||||||
|
zPaging.value?.complete([data])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.searchResult = data
|
||||||
|
} else {
|
||||||
|
zPaging.value?.complete([])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
resp.catch(() => {
|
||||||
|
zPaging.value?.complete([])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击取消搜索
|
||||||
|
const cancelSearch = () => {
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取key对应值
|
||||||
|
const getResultKeysValue = (keys) => {
|
||||||
|
let resultKey = ''
|
||||||
|
switch (keys) {
|
||||||
|
case 'user_infos':
|
||||||
|
resultKey = t('index.mine.addressBook')
|
||||||
|
break
|
||||||
|
case 'group_infos':
|
||||||
|
resultKey = t('chat.type.group')
|
||||||
|
break
|
||||||
|
case 'group_member_infos':
|
||||||
|
resultKey = t('chat.type.group')
|
||||||
|
break
|
||||||
|
case 'combinedGroup':
|
||||||
|
resultKey = t('chat.type.group')
|
||||||
|
break
|
||||||
|
case 'general_infos':
|
||||||
|
resultKey = t('chat.type.record')
|
||||||
|
break
|
||||||
|
case 'talk_record_infos':
|
||||||
|
resultKey = t('search.result.relevant') + t('chat.type.record')
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
resultKey = ''
|
||||||
|
}
|
||||||
|
return resultKey
|
||||||
|
}
|
||||||
|
|
||||||
|
//是否还有更多数据
|
||||||
|
const getHasMoreResult = (searchResultKey) => {
|
||||||
|
let has_more_result = ''
|
||||||
|
switch (searchResultKey) {
|
||||||
|
case 'user_infos':
|
||||||
|
if (
|
||||||
|
state.searchResult['user_count'] &&
|
||||||
|
state.searchResult['user_count'] > 3
|
||||||
|
) {
|
||||||
|
has_more_result = t('has_more') + t('index.mine.addressBook')
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'group_infos':
|
||||||
|
if (
|
||||||
|
state.searchResult['group_count'] &&
|
||||||
|
state.searchResult['group_count'] > 3
|
||||||
|
) {
|
||||||
|
has_more_result = t('has_more') + t('chat.type.group')
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'group_member_infos':
|
||||||
|
if (
|
||||||
|
state.searchResult['group_count'] &&
|
||||||
|
state.searchResult['group_count'] > 3
|
||||||
|
) {
|
||||||
|
has_more_result = t('has_more') + t('chat.type.group')
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'combinedGroup':
|
||||||
|
if (
|
||||||
|
state.searchResult['group_count'] &&
|
||||||
|
state.searchResult['group_count'] > 3
|
||||||
|
) {
|
||||||
|
has_more_result = t('has_more') + t('chat.type.group')
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'general_infos':
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
return has_more_result
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击跳转到更多结果页面
|
||||||
|
const toMoreResultPage = (searchResultKey) => {
|
||||||
|
emits('toMoreResultPage', searchResultKey, state.searchText)
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击了搜索结果项
|
||||||
|
const clickSearchItem = (searchResultKey, searchItem) => {
|
||||||
|
emits(
|
||||||
|
'clickSearchItem',
|
||||||
|
state.searchText,
|
||||||
|
searchResultKey,
|
||||||
|
searchItem.talk_type,
|
||||||
|
searchItem.receiver_id,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.search-list {
|
||||||
|
.searchRoot {
|
||||||
|
padding: 20rpx 48rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
.searchRoot_cancelBtn {
|
||||||
|
line-height: 44rpx;
|
||||||
|
color: $theme-primary;
|
||||||
|
margin: 0 0 0 20rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.search-record-detail {
|
||||||
|
padding: 0 50rpx;
|
||||||
|
}
|
||||||
|
.search-result {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 32rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: flex-start;
|
||||||
|
.search-result-list {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 18rpx;
|
||||||
|
|
||||||
|
.search-result-part {
|
||||||
|
margin: 36rpx 0 0;
|
||||||
|
|
||||||
|
.result-title {
|
||||||
|
padding: 0 0 10rpx;
|
||||||
|
span {
|
||||||
|
line-height: 40rpx;
|
||||||
|
color: $theme-hint-text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.result-has-more {
|
||||||
|
padding: 10px 0;
|
||||||
|
border-bottom: 1px solid $theme-border-color;
|
||||||
|
span {
|
||||||
|
color: #191919;
|
||||||
|
line-height: 40rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
50
src/pages/search/index.vue
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<div class="outer-layer search-page">
|
||||||
|
<div class="root">
|
||||||
|
<searchList
|
||||||
|
:searchResultPageSize="3"
|
||||||
|
:listLimit="true"
|
||||||
|
:apiRequest="ServeSeachQueryAll"
|
||||||
|
@toMoreResultPage="toMoreResultPage"
|
||||||
|
@clickSearchItem="clickSearchItem"
|
||||||
|
></searchList>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import searchList from './components/searchList.vue'
|
||||||
|
import { ServeSeachQueryAll } from '@/api/search/index'
|
||||||
|
|
||||||
|
//点击跳转到更多结果页面
|
||||||
|
const toMoreResultPage = (searchResultKey, searchText) => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url:
|
||||||
|
'/pages/search/moreResult/moreResult?searchResultKey=' +
|
||||||
|
searchResultKey +
|
||||||
|
'&searchText=' +
|
||||||
|
searchText,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击了搜索结果项
|
||||||
|
const clickSearchItem = (
|
||||||
|
searchText,
|
||||||
|
searchResultKey,
|
||||||
|
talk_type,
|
||||||
|
receiver_id,
|
||||||
|
) => {
|
||||||
|
console.log(searchResultKey)
|
||||||
|
if (searchResultKey === 'general_infos') {
|
||||||
|
uni.navigateTo({
|
||||||
|
url:
|
||||||
|
'/pages/search/moreResult/moreResultDetail?searchText=' +
|
||||||
|
searchText +
|
||||||
|
'&talk_type=' +
|
||||||
|
talk_type +
|
||||||
|
'&receiver_id=' +
|
||||||
|
receiver_id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss"></style>
|
97
src/pages/search/moreResult/moreResult.vue
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<div class="outer-layer search-page">
|
||||||
|
<div class="root">
|
||||||
|
<searchList
|
||||||
|
:searchResultPageSize="10"
|
||||||
|
:listLimit="false"
|
||||||
|
:apiRequest="state.apiRequest"
|
||||||
|
:apiParams="state.apiParams"
|
||||||
|
:searchText="state.searchText"
|
||||||
|
:isPagination="true"
|
||||||
|
@lastIdChange="lastIdChange"
|
||||||
|
@clickSearchItem="clickSearchItem"
|
||||||
|
></searchList>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import searchList from '../components/searchList.vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import {
|
||||||
|
ServeQueryUser,
|
||||||
|
ServeQueryGroup,
|
||||||
|
ServeTalkRecord,
|
||||||
|
} from '@/api/search/index'
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
apiRequest: Function,
|
||||||
|
apiParams: String,
|
||||||
|
searchText: String,
|
||||||
|
searchResultKey: String,
|
||||||
|
})
|
||||||
|
|
||||||
|
onLoad((options) => {
|
||||||
|
console.log(options)
|
||||||
|
if (options.searchResultKey) {
|
||||||
|
state.searchResultKey = options.searchResultKey
|
||||||
|
if (options.searchResultKey === 'user_infos') {
|
||||||
|
state.apiParams = encodeURIComponent(
|
||||||
|
JSON.stringify({
|
||||||
|
last_id: 0, //最后一条用户id
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
state.apiRequest = ServeQueryUser
|
||||||
|
} else if (options.searchResultKey === 'combinedGroup') {
|
||||||
|
state.apiParams = encodeURIComponent(
|
||||||
|
JSON.stringify({
|
||||||
|
last_group_id: 0, //最后一条群id
|
||||||
|
last_member_id: 0, //最后一条用户id
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
state.apiRequest = ServeQueryGroup
|
||||||
|
} else if (options.searchResultKey === 'general_infos') {
|
||||||
|
state.apiParams = encodeURIComponent(
|
||||||
|
JSON.stringify({
|
||||||
|
talk_type: 0, //1私聊2群聊
|
||||||
|
receiver_id: 0, //查详情的时候需传入
|
||||||
|
last_group_id: 0, //最后一条群id
|
||||||
|
last_member_id: 0, //最后一条用户id
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
state.apiRequest = ServeTalkRecord
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options.searchText) {
|
||||||
|
state.searchText = options.searchText
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//分页查询时,最后一条id变化
|
||||||
|
const lastIdChange = (last_id, last_group_id, last_member_id) => {
|
||||||
|
let idChanges = {
|
||||||
|
last_id,
|
||||||
|
last_group_id,
|
||||||
|
last_member_id,
|
||||||
|
}
|
||||||
|
state.apiParams = encodeURIComponent(
|
||||||
|
JSON.stringify(
|
||||||
|
Object.assign(
|
||||||
|
{},
|
||||||
|
JSON.parse(decodeURIComponent(state.apiParams)),
|
||||||
|
idChanges,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击了搜索结果项
|
||||||
|
const clickSearchItem = (searchText) => {
|
||||||
|
if (state.searchResultKey === 'general_infos') {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/search/moreResult/moreResultDetail?searchText=' + searchText,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss"></style>
|
71
src/pages/search/moreResult/moreResultDetail.vue
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<template>
|
||||||
|
<div class="outer-layer search-page">
|
||||||
|
<div class="root">
|
||||||
|
<searchList
|
||||||
|
:searchResultPageSize="10"
|
||||||
|
:listLimit="false"
|
||||||
|
:apiRequest="ServeTalkRecord"
|
||||||
|
:apiParams="state.apiParams"
|
||||||
|
:searchText="state.searchText"
|
||||||
|
:isPagination="true"
|
||||||
|
:searchRecordDetail="true"
|
||||||
|
@lastIdChange="lastIdChange"
|
||||||
|
></searchList>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import searchList from '../components/searchList.vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { ServeTalkRecord } from '@/api/search/index'
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
apiParams: String,
|
||||||
|
searchText: String,
|
||||||
|
})
|
||||||
|
|
||||||
|
onLoad((options) => {
|
||||||
|
console.log(options)
|
||||||
|
let talk_type = 0
|
||||||
|
if (options.talk_type) {
|
||||||
|
talk_type = Number(options.talk_type)
|
||||||
|
}
|
||||||
|
let receiver_id = 0
|
||||||
|
if (options.receiver_id) {
|
||||||
|
receiver_id = Number(options.receiver_id)
|
||||||
|
}
|
||||||
|
state.apiParams = encodeURIComponent(
|
||||||
|
JSON.stringify({
|
||||||
|
talk_type: talk_type, //1私聊2群聊
|
||||||
|
receiver_id: receiver_id, //查详情的时候需传入
|
||||||
|
last_group_id: 0, //最后一条群id
|
||||||
|
last_member_id: 0, //最后一条用户id
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
if (options.searchText) {
|
||||||
|
state.searchText = options.searchText
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(JSON.parse(decodeURIComponent(state.apiParams)))
|
||||||
|
})
|
||||||
|
|
||||||
|
//分页查询时,最后一条id变化
|
||||||
|
const lastIdChange = (last_id, last_group_id, last_member_id) => {
|
||||||
|
let idChanges = {
|
||||||
|
last_id,
|
||||||
|
last_group_id,
|
||||||
|
last_member_id,
|
||||||
|
}
|
||||||
|
state.apiParams = encodeURIComponent(
|
||||||
|
JSON.stringify(
|
||||||
|
Object.assign(
|
||||||
|
{},
|
||||||
|
JSON.parse(decodeURIComponent(state.apiParams)),
|
||||||
|
idChanges,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss"></style>
|
241
src/pages/search/searchByCondition/index.vue
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
<template>
|
||||||
|
<div class="outer-layer search-by-condition-page">
|
||||||
|
<div class="root">
|
||||||
|
<ZPaging ref="zPaging" :show-scrollbar="false">
|
||||||
|
<template #top>
|
||||||
|
<tm-navbar :hideBack="false" hideHome title="" :leftWidth="220">
|
||||||
|
<div class="navBar-title flex flex-col items-center justify-center">
|
||||||
|
<span class="text-[34rpx] font-medium">
|
||||||
|
{{ state.pageTitle }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</tm-navbar>
|
||||||
|
</template>
|
||||||
|
<div v-if="state.condition === 'date'" class="search-by-date">
|
||||||
|
<tm-time-picker
|
||||||
|
:show="state.showMonthPicker"
|
||||||
|
:showDetail="{
|
||||||
|
year: true,
|
||||||
|
month: true,
|
||||||
|
day: false,
|
||||||
|
hour: false,
|
||||||
|
minute: false,
|
||||||
|
second: false,
|
||||||
|
am_pm: false,
|
||||||
|
}"
|
||||||
|
:showSuffix="{
|
||||||
|
year: '',
|
||||||
|
month: '',
|
||||||
|
}"
|
||||||
|
:defaultValue="state.nowDate"
|
||||||
|
format="YYYY年MM月"
|
||||||
|
start=""
|
||||||
|
:end="state.maxDate"
|
||||||
|
@confirm="confirmSelectedMonth"
|
||||||
|
:round="0"
|
||||||
|
:title="$t('search.condition.date_pickerTitle')"
|
||||||
|
>
|
||||||
|
<div class="search-date-picker">
|
||||||
|
<span class="text-[28rpx] font-regular">
|
||||||
|
{{ state.selectedMonth }}
|
||||||
|
</span>
|
||||||
|
<img src="/src/static/image/search/down-pointer.png" />
|
||||||
|
</div>
|
||||||
|
</tm-time-picker>
|
||||||
|
<tm-calendar-view
|
||||||
|
:show="true"
|
||||||
|
:hideTool="true"
|
||||||
|
:hideButton="true"
|
||||||
|
:dateStyle="state.dateStyle"
|
||||||
|
:defaultValue="state.selectedDateArray"
|
||||||
|
v-model="state.selectedDateArray"
|
||||||
|
:disabledDate="state.disabledDateArray"
|
||||||
|
@click="selectDate"
|
||||||
|
model="day"
|
||||||
|
:end="state.maxDate"
|
||||||
|
@getDArray="getDArray"
|
||||||
|
:showDefault="false"
|
||||||
|
></tm-calendar-view>
|
||||||
|
</div>
|
||||||
|
</ZPaging>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
|
||||||
|
import searchList from '../components/searchList.vue'
|
||||||
|
import { parseTime } from '@/utils/datetime'
|
||||||
|
import { onMounted, reactive } from 'vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { ServeTalkDate } from '@/api/search/index'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
let nowDay = new Date().setHours(0, 0, 0, 0)
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
receiver_id: '', //目标人id
|
||||||
|
pageTitle: '', //页面标题
|
||||||
|
dateStyle: [], //日期样式
|
||||||
|
nowDate: new Date(nowDay), //当前时间
|
||||||
|
maxDate: new Date(nowDay), //可选择最大时间
|
||||||
|
selectedDateArray: Array(new Date(nowDay)), //选择的月份数组
|
||||||
|
showMonthPicker: false, //是否显示月份选择
|
||||||
|
selectedMonth: new Date(nowDay), //当前选择的月份
|
||||||
|
disabledDateArray: [], //被禁用的日期数组
|
||||||
|
dArray: [], //日历日期数组
|
||||||
|
})
|
||||||
|
|
||||||
|
onLoad((options) => {
|
||||||
|
console.log(options)
|
||||||
|
if (options.receiver_id) {
|
||||||
|
state.receiver_id = Number(options.receiver_id)
|
||||||
|
}
|
||||||
|
if (options.condition) {
|
||||||
|
state.condition = options.condition
|
||||||
|
if (options.condition === 'date') {
|
||||||
|
state.pageTitle = t('search.condition.date')
|
||||||
|
ServeQueryTalkDate(parseTime(state.nowDate, '{y}{m}'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
state.selectedMonth = parseTime(state.selectedMonth, '{y}年{m}月')
|
||||||
|
state.dateStyle = [
|
||||||
|
{
|
||||||
|
date: state.nowDate, //日期
|
||||||
|
text: false, //浅色背景。
|
||||||
|
color: '#46299D', //主题色.
|
||||||
|
extra: '今天', //额外的内容,在日期下方显示的文本。
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
//查看存在聊天记录的天数
|
||||||
|
const ServeQueryTalkDate = (month) => {
|
||||||
|
let params = {
|
||||||
|
month: month,
|
||||||
|
talk_type: 2, //1私聊2群聊
|
||||||
|
receiver_id: state.receiver_id, //目标人id
|
||||||
|
}
|
||||||
|
const resp = ServeTalkDate(params)
|
||||||
|
console.log(resp)
|
||||||
|
resp.then(({ code, data }) => {
|
||||||
|
console.log(data)
|
||||||
|
if (code == 200) {
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
const formattedData = data.map(
|
||||||
|
(item) =>
|
||||||
|
item.substring(0, 4) +
|
||||||
|
'/' +
|
||||||
|
item.substring(4, 6) +
|
||||||
|
'/' +
|
||||||
|
item.substring(6, 8),
|
||||||
|
)
|
||||||
|
let disabledDateArray = state.dArray.filter(
|
||||||
|
(dIt) => !formattedData.includes(dIt),
|
||||||
|
)
|
||||||
|
disabledDateArray = disabledDateArray.map((item) =>
|
||||||
|
item.replace(/\//g, '-'),
|
||||||
|
)
|
||||||
|
console.log(disabledDateArray)
|
||||||
|
state.disabledDateArray = disabledDateArray
|
||||||
|
} else {
|
||||||
|
state.disabledDateArray = state.dArray
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
resp.catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击选择日期
|
||||||
|
const selectDate = (e) => {
|
||||||
|
if (e == parseTime(state.nowDate, '{y}/{m}/{d}')) {
|
||||||
|
console.log('==今日')
|
||||||
|
state.dateStyle = [
|
||||||
|
{
|
||||||
|
date: state.nowDate, //日期
|
||||||
|
text: false, //浅色背景。
|
||||||
|
color: '#46299D', //主题色.
|
||||||
|
extra: '今天', //额外的内容,在日期下方显示的文本。
|
||||||
|
},
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
state.dateStyle = [
|
||||||
|
{
|
||||||
|
date: state.nowDate, //日期
|
||||||
|
text: false, //浅色背景。
|
||||||
|
color: '', //主题色.
|
||||||
|
extra: '今天', //额外的内容,在日期下方显示的文本。
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date(e), //日期
|
||||||
|
text: false, //浅色背景。
|
||||||
|
color: '#46299D', //主题色.
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击确认选择月份
|
||||||
|
const confirmSelectedMonth = (e) => {
|
||||||
|
console.log(e)
|
||||||
|
state.selectedMonth = parseTime(e, '{y}年{m}月')
|
||||||
|
// console.log()
|
||||||
|
let newDate = new Date(e)
|
||||||
|
newDate.setHours(0, 0, 0, 0)
|
||||||
|
newDate.setDate(1)
|
||||||
|
state.selectedDateArray = Array(new Date(newDate))
|
||||||
|
state.dateStyle = [
|
||||||
|
{
|
||||||
|
date: state.nowDate, //日期
|
||||||
|
text: false, //浅色背景。
|
||||||
|
color: '', //主题色.
|
||||||
|
extra: '今天', //额外的内容,在日期下方显示的文本。
|
||||||
|
},
|
||||||
|
]
|
||||||
|
ServeQueryTalkDate(parseTime(e, '{y}{m}'))
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取日历日期数组
|
||||||
|
const getDArray = (dArray) => {
|
||||||
|
state.dArray = dArray
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.search-by-date {
|
||||||
|
.search-date-picker {
|
||||||
|
padding: 20rpx 32rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
span {
|
||||||
|
line-height: 40rpx;
|
||||||
|
color: $theme-hint-text;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
width: 18rpx;
|
||||||
|
height: 11rpx;
|
||||||
|
margin: 0 0 0 26rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body::v-deep .text-overflow-1 {
|
||||||
|
color: #666666 !important;
|
||||||
|
line-height: 44rpx !important;
|
||||||
|
font-size: 32rpx !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
}
|
||||||
|
body::v-deep .tmicon-times-circle-fill {
|
||||||
|
width: 37rpx;
|
||||||
|
height: 37rpx;
|
||||||
|
}
|
||||||
|
body::v-deep .round-3 {
|
||||||
|
background: linear-gradient(to right, #674bbc, #46299d);
|
||||||
|
}
|
||||||
|
</style>
|
@ -1 +1,4 @@
|
|||||||
$theme-primary: #46299D;
|
$theme-primary: #46299d;
|
||||||
|
$theme-text: #191919;
|
||||||
|
$theme-hint-text: #999999;
|
||||||
|
$theme-border-color: #f8f8f8;
|
||||||
|
3
src/static/css/font.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.font-regular {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
BIN
src/static/image/chatSettings/add-btn.png
Normal file
After Width: | Height: | Size: 795 B |
BIN
src/static/image/chatSettings/app-icon.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
src/static/image/chatSettings/clear-btn.png
Normal file
After Width: | Height: | Size: 297 B |
BIN
src/static/image/chatSettings/edit-btn.png
Normal file
After Width: | Height: | Size: 519 B |
BIN
src/static/image/chatSettings/pointer.png
Normal file
After Width: | Height: | Size: 370 B |
BIN
src/static/image/chatSettings/recordSearchTypeDate.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
src/static/image/chatSettings/recordSearchTypeFiles.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
src/static/image/chatSettings/recordSearchTypeGroupMembers.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
src/static/image/chatSettings/recordSearchTypeImgAndVideo.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
src/static/image/chatSettings/recordSearchTypeLink.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
src/static/image/search/down-pointer.png
Normal file
After Width: | Height: | Size: 208 B |
BIN
src/static/image/search/search-item-pointer.png
Normal file
After Width: | Height: | Size: 370 B |
BIN
src/static/image/search/search-no-data.png
Normal file
After Width: | Height: | Size: 26 KiB |
@ -7,3 +7,4 @@ export * from '@/store/modules/editor-draft'
|
|||||||
export * from '@/store/modules/uploads'
|
export * from '@/store/modules/uploads'
|
||||||
export * from '@/store/modules/dialogueList'
|
export * from '@/store/modules/dialogueList'
|
||||||
// export * from '@/store/modules/note'
|
// export * from '@/store/modules/note'
|
||||||
|
export * from '@/store/modules/group'
|
||||||
|
@ -3,7 +3,7 @@ import {
|
|||||||
ServeRemoveRecords,
|
ServeRemoveRecords,
|
||||||
ServeRevokeRecords,
|
ServeRevokeRecords,
|
||||||
ServePublishMessage,
|
ServePublishMessage,
|
||||||
ServeCollectEmoticon
|
ServeCollectEmoticon,
|
||||||
} from '@/api/chat/index'
|
} from '@/api/chat/index'
|
||||||
import { ServeGetGroupMembers } from '@/api/group/index'
|
import { ServeGetGroupMembers } from '@/api/group/index'
|
||||||
import { useEditorStore } from './editor'
|
import { useEditorStore } from './editor'
|
||||||
@ -22,7 +22,7 @@ export const useDialogueStore = defineStore('dialogue', {
|
|||||||
talk: {
|
talk: {
|
||||||
username: '',
|
username: '',
|
||||||
talk_type: 0, // 对话来源[1:私聊;2:群聊]
|
talk_type: 0, // 对话来源[1:私聊;2:群聊]
|
||||||
receiver_id: 0
|
receiver_id: 0,
|
||||||
},
|
},
|
||||||
|
|
||||||
// 好友是否正在输入文字
|
// 好友是否正在输入文字
|
||||||
@ -55,20 +55,26 @@ export const useDialogueStore = defineStore('dialogue', {
|
|||||||
talk_type: 1, // 对话类型
|
talk_type: 1, // 对话类型
|
||||||
receiver_id: 0, // 接收者ID
|
receiver_id: 0, // 接收者ID
|
||||||
read_sequence: 0, // 当前已读的最后一条记录
|
read_sequence: 0, // 当前已读的最后一条记录
|
||||||
records: []
|
records: [],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
// 转发消息类型
|
// 转发消息类型
|
||||||
forwardType: 1,
|
forwardType: 1,
|
||||||
// 合并转发消息
|
// 合并转发消息
|
||||||
forwardMessages: []
|
forwardMessages: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
// 多选列表
|
// 多选列表
|
||||||
selectItems: (state) => state.records.filter((item) => item.isCheck),
|
selectItems: (state) => state.records.filter((item) => item.isCheck),
|
||||||
// 当前对话是否是群聊
|
// 当前对话是否是群聊
|
||||||
isGroupTalk: (state) => state.talk.talk_type === 2
|
isGroupTalk: (state) => state.talk.talk_type === 2,
|
||||||
|
//获取被禁言的成员列表
|
||||||
|
getSilenceMember: (state) =>
|
||||||
|
state.members.filter((item) => item.is_mute === 1),
|
||||||
|
//获取群管理员
|
||||||
|
getAdminList: (state) =>
|
||||||
|
state.members.filter((item) => item.leader === 1),
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
// 更新在线状态
|
// 更新在线状态
|
||||||
@ -82,7 +88,7 @@ export const useDialogueStore = defineStore('dialogue', {
|
|||||||
this.talk = {
|
this.talk = {
|
||||||
username: data.remark || data.name,
|
username: data.remark || data.name,
|
||||||
talk_type: data.talk_type,
|
talk_type: data.talk_type,
|
||||||
receiver_id: data.receiver_id
|
receiver_id: data.receiver_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.index_name = `${data.talk_type}_${data.receiver_id}`
|
this.index_name = `${data.talk_type}_${data.receiver_id}`
|
||||||
@ -99,7 +105,7 @@ export const useDialogueStore = defineStore('dialogue', {
|
|||||||
// 更新提及列表
|
// 更新提及列表
|
||||||
async updateGroupMembers() {
|
async updateGroupMembers() {
|
||||||
let { code, data } = await ServeGetGroupMembers({
|
let { code, data } = await ServeGetGroupMembers({
|
||||||
group_id: this.talk.receiver_id
|
group_id: this.talk.receiver_id,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (code != 200) return
|
if (code != 200) return
|
||||||
@ -112,7 +118,8 @@ export const useDialogueStore = defineStore('dialogue', {
|
|||||||
leader: o.leader,
|
leader: o.leader,
|
||||||
remark: o.remark,
|
remark: o.remark,
|
||||||
online: false,
|
online: false,
|
||||||
value: o.nickname
|
value: o.nickname,
|
||||||
|
key: o.key
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -191,7 +198,7 @@ export const useDialogueStore = defineStore('dialogue', {
|
|||||||
ServeRemoveRecords({
|
ServeRemoveRecords({
|
||||||
talk_type: this.talk.talk_type,
|
talk_type: this.talk.talk_type,
|
||||||
receiver_id: this.talk.receiver_id,
|
receiver_id: this.talk.receiver_id,
|
||||||
msg_ids: msgIds
|
msg_ids: msgIds,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
this.batchDelDialogueRecord(msgIds)
|
this.batchDelDialogueRecord(msgIds)
|
||||||
@ -219,9 +226,9 @@ export const useDialogueStore = defineStore('dialogue', {
|
|||||||
type: 'forward',
|
type: 'forward',
|
||||||
receiver: {
|
receiver: {
|
||||||
talk_type: this.talk.talk_type,
|
talk_type: this.talk.talk_type,
|
||||||
receiver_id: this.talk.receiver_id
|
receiver_id: this.talk.receiver_id,
|
||||||
},
|
},
|
||||||
...options
|
...options,
|
||||||
}
|
}
|
||||||
|
|
||||||
ServePublishMessage(data).then((res) => {
|
ServePublishMessage(data).then((res) => {
|
||||||
@ -247,6 +254,6 @@ export const useDialogueStore = defineStore('dialogue', {
|
|||||||
// 设置合并转发消息
|
// 设置合并转发消息
|
||||||
setForwardMessages(messages) {
|
setForwardMessages(messages) {
|
||||||
this.forwardMessages = messages
|
this.forwardMessages = messages
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
47
src/store/modules/group.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import {
|
||||||
|
ServeGroupDetail,
|
||||||
|
ServeGetGroupMembers,
|
||||||
|
ServeGetGroupNotices,
|
||||||
|
} from '@/api/group/index'
|
||||||
|
import { useDialogueStore } from '@/store'
|
||||||
|
|
||||||
|
export const useGroupStore = defineStore('group', {
|
||||||
|
state: () => {
|
||||||
|
return {
|
||||||
|
groupInfo: '', //群聊信息
|
||||||
|
memberList: [], //群成员列表
|
||||||
|
groupNotice: [], //群公告
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
//获取群聊信息
|
||||||
|
getGroupInfo: (state) => state.groupInfo,
|
||||||
|
//获取群公告
|
||||||
|
getGroupNotice: (state) => state.groupNotice,
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
//获取群聊信息
|
||||||
|
async ServeGroupDetail() {
|
||||||
|
const dialogueStore = useDialogueStore()
|
||||||
|
let { code, data } = await ServeGroupDetail({
|
||||||
|
group_id: dialogueStore.talk.receiver_id,
|
||||||
|
})
|
||||||
|
if (code == 200) {
|
||||||
|
console.log(data)
|
||||||
|
this.groupInfo = data
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//群公告查询
|
||||||
|
async ServeGetGroupNotices() {
|
||||||
|
const dialogueStore = useDialogueStore()
|
||||||
|
let { code, data } = await ServeGetGroupNotices({
|
||||||
|
group_id: dialogueStore.talk.receiver_id,
|
||||||
|
})
|
||||||
|
if (code == 200) {
|
||||||
|
this.groupNotice = data.items
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
@ -18,6 +18,10 @@ export const useTalkStore = defineStore('talk', {
|
|||||||
topItems: (state) => {
|
topItems: (state) => {
|
||||||
return state.items.filter((item) => item.is_top == 1)
|
return state.items.filter((item) => item.is_top == 1)
|
||||||
},
|
},
|
||||||
|
// 过滤所有免打扰对话列表
|
||||||
|
disturbItems: (state) => {
|
||||||
|
return state.items.filter((item) => item.is_disturb == 1)
|
||||||
|
},
|
||||||
|
|
||||||
// 对话列表
|
// 对话列表
|
||||||
talkItems: (state) => {
|
talkItems: (state) => {
|
||||||
|
@ -1,41 +1,93 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="flex flex-col relative">
|
<view class="flex flex-col relative">
|
||||||
<tm-sheet v-if="!props.hideTool" :shadow="0" :round="0" :height="88" :margin="[0, 0]" :padding="[0, 0]" _class="flex flex-col">
|
<tm-sheet
|
||||||
<view class="flex flex-row flex-row-center-center" style="height: 88rpx">
|
v-if="!props.hideTool"
|
||||||
|
:shadow="0"
|
||||||
|
:round="0"
|
||||||
|
:height="88"
|
||||||
|
:margin="[0, 0]"
|
||||||
|
:padding="[0, 0]"
|
||||||
|
_class="flex flex-col"
|
||||||
|
>
|
||||||
|
<view class="flex flex-row flex-row-center-center" style="height: 88rpx;">
|
||||||
<view @click.stop="prevYear" class="px-16">
|
<view @click.stop="prevYear" class="px-16">
|
||||||
<tm-icon :userInteractionEnabled="false" :font-size="22" name="tmicon-angle-double-left"></tm-icon>
|
<tm-icon
|
||||||
|
:userInteractionEnabled="false"
|
||||||
|
:font-size="22"
|
||||||
|
name="tmicon-angle-double-left"
|
||||||
|
></tm-icon>
|
||||||
</view>
|
</view>
|
||||||
<view @click.stop="prevMonth" class="px-16">
|
<view @click.stop="prevMonth" class="px-16">
|
||||||
<tm-icon :userInteractionEnabled="false" :font-size="22" name="tmicon-angle-left"></tm-icon>
|
<tm-icon
|
||||||
|
:userInteractionEnabled="false"
|
||||||
|
:font-size="22"
|
||||||
|
name="tmicon-angle-left"
|
||||||
|
></tm-icon>
|
||||||
</view>
|
</view>
|
||||||
<view class="px-12">
|
<view class="px-12">
|
||||||
<tm-text :userInteractionEnabled="false" _class="text-weight-b" :font-size="32" :label="_nowDate"></tm-text>
|
<tm-text
|
||||||
|
:userInteractionEnabled="false"
|
||||||
|
_class="text-weight-b"
|
||||||
|
:font-size="32"
|
||||||
|
:label="_nowDate"
|
||||||
|
></tm-text>
|
||||||
</view>
|
</view>
|
||||||
<view @click.stop="nextMonth" class="px-16">
|
<view @click.stop="nextMonth" class="px-16">
|
||||||
<tm-icon :userInteractionEnabled="false" :font-size="22" name="tmicon-angle-right"></tm-icon>
|
<tm-icon
|
||||||
|
:userInteractionEnabled="false"
|
||||||
|
:font-size="22"
|
||||||
|
name="tmicon-angle-right"
|
||||||
|
></tm-icon>
|
||||||
</view>
|
</view>
|
||||||
<view @click.stop="nextYear" class="px-16">
|
<view @click.stop="nextYear" class="px-16">
|
||||||
<tm-icon :userInteractionEnabled="false" :font-size="22" name="tmicon-angle-double-right"></tm-icon>
|
<tm-icon
|
||||||
|
:userInteractionEnabled="false"
|
||||||
|
:font-size="22"
|
||||||
|
name="tmicon-angle-double-right"
|
||||||
|
></tm-icon>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view
|
||||||
@click="nowWeekClick"
|
@click="nowWeekClick"
|
||||||
class="absolute t-0 r--6 zIndex-10 round-12 py-4 flex flex-row flex-row-center-center"
|
class="absolute t-0 r--6 zIndex-10 round-12 py-4 flex flex-row flex-row-center-center"
|
||||||
style="width: 90rpx; height: 88rpx"
|
style="width: 90rpx; height: 88rpx;"
|
||||||
>
|
>
|
||||||
<tm-text :userInteractionEnabled="false" color="grey" _class="text-align-center" :font-size="28" :label="props.textUnit[8]"></tm-text>
|
<tm-text
|
||||||
|
:userInteractionEnabled="false"
|
||||||
|
color="grey"
|
||||||
|
_class="text-align-center"
|
||||||
|
:font-size="28"
|
||||||
|
:label="props.textUnit[8]"
|
||||||
|
></tm-text>
|
||||||
</view>
|
</view>
|
||||||
</tm-sheet>
|
</tm-sheet>
|
||||||
<view class="flex flex-row flex-row-center-center py-12" :style="[{ height: '74rpx' }]">
|
<view
|
||||||
<view class="flex-1 flex-center" v-for="(item, index) in weekStr" :key="index">
|
class="flex flex-row flex-row-center-center py-12"
|
||||||
<view style="width: 62rpx" class="flex-center flex-col">
|
:style="[{ height: '74rpx' }]"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="flex-1 flex-center"
|
||||||
|
v-for="(item, index) in weekStr"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<view style="width: 62rpx;" class="flex-center flex-col">
|
||||||
<tm-text :font-size="24" :label="item"></tm-text>
|
<tm-text :font-size="24" :label="item"></tm-text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex flex-col">
|
<view class="flex flex-col">
|
||||||
<view class="flex flex-row flex-row-center-center" :style="[{ height: '94rpx' }]" v-for="(item, index) in _data" :key="index">
|
<view
|
||||||
<view @click="clickWeek(item2)" class="flex-1 flex flex-row flex-row-center-center" v-for="(item2, index2) in item" :key="index2">
|
class="flex flex-row flex-row-center-center"
|
||||||
|
:style="[{ height: '94rpx' }]"
|
||||||
|
v-for="(item, index) in _data"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
@click="clickWeek(item2)"
|
||||||
|
class="flex-1 flex flex-row flex-row-center-center"
|
||||||
|
v-for="(item2, index2) in item"
|
||||||
|
:key="index2"
|
||||||
|
>
|
||||||
<tm-sheet
|
<tm-sheet
|
||||||
:userInteractionEnabled="false"
|
:userInteractionEnabled="false"
|
||||||
:height="90"
|
:height="90"
|
||||||
@ -45,19 +97,34 @@
|
|||||||
:border="item2.extra.color && isSelected(item2.dateStr) ? 1 : 0"
|
:border="item2.extra.color && isSelected(item2.dateStr) ? 1 : 0"
|
||||||
_class="flex-row"
|
_class="flex-row"
|
||||||
:transprent="item2.extra.color || !isSelected(item2.dateStr)"
|
:transprent="item2.extra.color || !isSelected(item2.dateStr)"
|
||||||
:color="item2.extra.color ? item2.extra.color : isSelected(item2.dateStr) ? _color : 'white'"
|
:color="
|
||||||
|
item2.extra.color
|
||||||
|
? item2.extra.color
|
||||||
|
: isSelected(item2.dateStr)
|
||||||
|
? _color
|
||||||
|
: 'white'
|
||||||
|
"
|
||||||
:margin="[0, 0]"
|
:margin="[0, 0]"
|
||||||
:padding="[0, 0]"
|
:padding="[0, 0]"
|
||||||
>
|
>
|
||||||
<view
|
<view
|
||||||
:userInteractionEnabled="false"
|
:userInteractionEnabled="false"
|
||||||
style="width: 62rpx"
|
style="width: 62rpx;"
|
||||||
:class="[!item2.isNowIn ? 'opacity-6' : '']"
|
:class="[!item2.isNowIn ? 'opacity-6' : '']"
|
||||||
class="flex-1 flex-center"
|
class="flex-1 flex-center"
|
||||||
>
|
>
|
||||||
<view style="width: 62rpx" class="flex-center flex-col" :style="[{ opacity: item2.disabled ? '0.3' : '1' }]">
|
<view
|
||||||
|
style="width: 62rpx;"
|
||||||
|
class="flex-center flex-col"
|
||||||
|
:style="[{ opacity: item2.disabled ? '0.3' : '1' }]"
|
||||||
|
>
|
||||||
<tm-text :font-size="28" :label="item2.date"></tm-text>
|
<tm-text :font-size="28" :label="item2.date"></tm-text>
|
||||||
<tm-text _class="flex-center" v-if="item2.extra.extra" :font-size="22" :label="item2.extra.extra"></tm-text>
|
<tm-text
|
||||||
|
_class="flex-center"
|
||||||
|
v-if="item2.extra.extra"
|
||||||
|
:font-size="22"
|
||||||
|
:label="item2.extra.extra"
|
||||||
|
></tm-text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</tm-sheet>
|
</tm-sheet>
|
||||||
@ -103,84 +170,112 @@ const store = useTmpiniaStore()
|
|||||||
* click-day 日期被选中时触发,注意禁用的日期不会触发 。
|
* click-day 日期被选中时触发,注意禁用的日期不会触发 。
|
||||||
* change 当切换年或者月的时候触发。
|
* change 当切换年或者月的时候触发。
|
||||||
*/
|
*/
|
||||||
const emits = defineEmits(['update:modelValue', 'confirm', 'click-day', 'change'])
|
const emits = defineEmits([
|
||||||
|
'update:modelValue',
|
||||||
|
'confirm',
|
||||||
|
'click-day',
|
||||||
|
'change',
|
||||||
|
'getDArray',
|
||||||
|
])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
followTheme: {
|
followTheme: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true,
|
||||||
},
|
},
|
||||||
//默认显示的日期
|
//默认显示的日期
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
type: Array as PropType<Array<String | Number | Date>>,
|
type: Array as PropType<Array<String | Number | Date>>,
|
||||||
default: () => []
|
default: () => [],
|
||||||
},
|
},
|
||||||
//当前的周时间段
|
//当前的周时间段
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Array as PropType<Array<String | Number | Date>>,
|
type: Array as PropType<Array<String | Number | Date>>,
|
||||||
default: () => []
|
default: () => [],
|
||||||
},
|
},
|
||||||
color: {
|
color: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'primary'
|
default: 'primary',
|
||||||
},
|
},
|
||||||
linear: {
|
linear: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
linearDeep: {
|
linearDeep: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'light'
|
default: 'light',
|
||||||
},
|
},
|
||||||
//指的是:有效的可选时间,小于此时间,不允许选中。
|
//指的是:有效的可选时间,小于此时间,不允许选中。
|
||||||
start: {
|
start: {
|
||||||
type: [String, Number, Date],
|
type: [String, Number, Date],
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
//指的是:有效的可选时间,大于此时间,不允许选中。
|
//指的是:有效的可选时间,大于此时间,不允许选中。
|
||||||
end: {
|
end: {
|
||||||
type: [String, Number, Date],
|
type: [String, Number, Date],
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
//被禁用的日期数组。如果["2022-1-1","2022-5-1"]
|
//被禁用的日期数组。如果["2022-1-1","2022-5-1"]
|
||||||
//被禁用的日期将无法选中。
|
//被禁用的日期将无法选中。
|
||||||
disabledDate: {
|
disabledDate: {
|
||||||
type: Array as PropType<Array<String | Number | Date>>,
|
type: Array as PropType<Array<String | Number | Date>>,
|
||||||
default: () => []
|
default: () => [],
|
||||||
},
|
},
|
||||||
//是否允许多选。
|
//是否允许多选。
|
||||||
multiple: {
|
multiple: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
//设定单个日期的样式。
|
//设定单个日期的样式。
|
||||||
dateStyle: {
|
dateStyle: {
|
||||||
type: Array as PropType<Array<dateItemStyle>>,
|
type: Array as PropType<Array<dateItemStyle>>,
|
||||||
default: () => []
|
default: () => [],
|
||||||
},
|
},
|
||||||
//当multiple=true时,可以选择的最大日期数量。
|
//当multiple=true时,可以选择的最大日期数量。
|
||||||
max: {
|
max: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 999
|
default: 999,
|
||||||
},
|
},
|
||||||
//隐藏头部操作栏
|
//隐藏头部操作栏
|
||||||
hideTool: {
|
hideTool: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
//隐藏底部确认按钮
|
//隐藏底部确认按钮
|
||||||
hideButton: {
|
hideButton: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
confirmText: {
|
confirmText: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '确认'
|
default: '确认',
|
||||||
},
|
},
|
||||||
//周次,本日、本季、本年、本月、本周的文字请按顺序提供文本,方便定义其它语言。
|
//周次,本日、本季、本年、本月、本周的文字请按顺序提供文本,方便定义其它语言。
|
||||||
textUnit: {
|
textUnit: {
|
||||||
type: Array as PropType<string[]>,
|
type: Array as PropType<string[]>,
|
||||||
default: ['周次','一','二','三','四','五','六','日','本日','本周','本月','本季度','本年','月','第${x}季度','年']
|
default: [
|
||||||
}
|
'周次',
|
||||||
|
'一',
|
||||||
|
'二',
|
||||||
|
'三',
|
||||||
|
'四',
|
||||||
|
'五',
|
||||||
|
'六',
|
||||||
|
'日',
|
||||||
|
'本日',
|
||||||
|
'本周',
|
||||||
|
'本月',
|
||||||
|
'本季度',
|
||||||
|
'本年',
|
||||||
|
'月',
|
||||||
|
'第${x}季度',
|
||||||
|
'年',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
showDefault: {
|
||||||
|
//是否显示被选中的默认样式
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
const _color = computed(() => {
|
const _color = computed(() => {
|
||||||
if (props.followTheme && store.tmStore.color) return store.tmStore.color
|
if (props.followTheme && store.tmStore.color) return store.tmStore.color
|
||||||
@ -218,13 +313,19 @@ const _nowDate = computed(() => {
|
|||||||
_data.value = getWeekOfMonthArray()
|
_data.value = getWeekOfMonthArray()
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
[() => props.modelValue, () => props.dateStyle, () => props.disabledDate, () => props.start, () => props.end],
|
[
|
||||||
|
() => props.modelValue,
|
||||||
|
() => props.dateStyle,
|
||||||
|
() => props.disabledDate,
|
||||||
|
() => props.start,
|
||||||
|
() => props.end,
|
||||||
|
],
|
||||||
() => {
|
() => {
|
||||||
_value.value = props.modelValue
|
_value.value = props.modelValue
|
||||||
showOpenDate.value = setShowopenDate()
|
showOpenDate.value = setShowopenDate()
|
||||||
_data.value = getWeekOfMonthArray()
|
_data.value = getWeekOfMonthArray(true)
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
//设置当前需要展示的月份。
|
//设置当前需要展示的月份。
|
||||||
@ -251,7 +352,9 @@ function nowWeekClick() {
|
|||||||
}
|
}
|
||||||
function clickWeek(wk: monthDayItem) {
|
function clickWeek(wk: monthDayItem) {
|
||||||
if (wk.disabled) {
|
if (wk.disabled) {
|
||||||
|
if (props.showDefault) {
|
||||||
uni.showToast({ title: '无法选中', icon: 'none' })
|
uni.showToast({ title: '无法选中', icon: 'none' })
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
selected(wk.dateStr)
|
selected(wk.dateStr)
|
||||||
@ -314,7 +417,7 @@ function setDefault(data: Array<String | Number | Date> = []) {
|
|||||||
_data.value = getWeekOfMonthArray()
|
_data.value = getWeekOfMonthArray()
|
||||||
}
|
}
|
||||||
//获取本月按周分组的时间段。
|
//获取本月按周分组的时间段。
|
||||||
function getWeekOfMonthArray() {
|
function getWeekOfMonthArray(needDarray = false) {
|
||||||
let nowMonth: dayjs.Dayjs = showOpenDate.value.date(1)
|
let nowMonth: dayjs.Dayjs = showOpenDate.value.date(1)
|
||||||
let startStatickDay = nowMonth.startOf('month')
|
let startStatickDay = nowMonth.startOf('month')
|
||||||
let endStatickDay = nowMonth.endOf('month')
|
let endStatickDay = nowMonth.endOf('month')
|
||||||
@ -359,8 +462,8 @@ function getWeekOfMonthArray() {
|
|||||||
text: false,
|
text: false,
|
||||||
color: '',
|
color: '',
|
||||||
extra: '',
|
extra: '',
|
||||||
...ext
|
...ext,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
arOfmonth.push(startd.isoWeek())
|
arOfmonth.push(startd.isoWeek())
|
||||||
startd = startd.add(1, 'day')
|
startd = startd.add(1, 'day')
|
||||||
@ -387,10 +490,20 @@ function getWeekOfMonthArray() {
|
|||||||
dArray[index].push(el)
|
dArray[index].push(el)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
if (needDarray) {
|
||||||
|
let datesArr: Array<String> = []
|
||||||
|
ar.forEach((it) => {
|
||||||
|
datesArr.push(it.dateStr)
|
||||||
|
})
|
||||||
|
emits('getDArray', datesArr)
|
||||||
|
}
|
||||||
return dArray
|
return dArray
|
||||||
}
|
}
|
||||||
// 检测now日期是否在某个日期的月份中.
|
// 检测now日期是否在某个日期的月份中.
|
||||||
function isInNowMonth(date: string | dayjs.Dayjs | number = '', now: string | dayjs.Dayjs | number = '') {
|
function isInNowMonth(
|
||||||
|
date: string | dayjs.Dayjs | number = '',
|
||||||
|
now: string | dayjs.Dayjs | number = '',
|
||||||
|
) {
|
||||||
let startStatickDay = DayJs(date).startOf('month').format('YYYY/MM/DD')
|
let startStatickDay = DayJs(date).startOf('month').format('YYYY/MM/DD')
|
||||||
let endStatickDay = DayJs(date).endOf('month').format('YYYY/MM/DD')
|
let endStatickDay = DayJs(date).endOf('month').format('YYYY/MM/DD')
|
||||||
return DayJs(now).isBetween(startStatickDay, endStatickDay, 'day', '[]')
|
return DayJs(now).isBetween(startStatickDay, endStatickDay, 'day', '[]')
|
||||||
@ -413,7 +526,7 @@ function isDisabledDate(date: string | dayjs.Dayjs | number = '') {
|
|||||||
function isSelected(date: string | dayjs.Dayjs | number = '') {
|
function isSelected(date: string | dayjs.Dayjs | number = '') {
|
||||||
let fr = _value.value.filter((el) => DayJs(el).isSame(date))
|
let fr = _value.value.filter((el) => DayJs(el).isSame(date))
|
||||||
|
|
||||||
return fr.length > 0
|
return fr.length > 0 && props.showDefault
|
||||||
}
|
}
|
||||||
|
|
||||||
function confirm() {
|
function confirm() {
|
||||||
@ -428,7 +541,7 @@ defineExpose({
|
|||||||
nextYear: nextYear,
|
nextYear: nextYear,
|
||||||
nextMonth: nextMonth,
|
nextMonth: nextMonth,
|
||||||
prevYear: prevYear,
|
prevYear: prevYear,
|
||||||
prevMonth: prevMonth
|
prevMonth: prevMonth,
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
:linearDeep="props.linearDeep"
|
:linearDeep="props.linearDeep"
|
||||||
></range-day>
|
></range-day>
|
||||||
<month-day
|
<month-day
|
||||||
|
:showDefault="props.showDefault"
|
||||||
|
@getDArray="getDArray"
|
||||||
:confirmText="_confirmText"
|
:confirmText="_confirmText"
|
||||||
:textUnit="_textUnit"
|
:textUnit="_textUnit"
|
||||||
:hideButton="props.hideButton"
|
:hideButton="props.hideButton"
|
||||||
@ -139,8 +141,23 @@
|
|||||||
* 日历(嵌入页面面板)
|
* 日历(嵌入页面面板)
|
||||||
* @description 可以按月,按日,按周,按季度显示
|
* @description 可以按月,按日,按周,按季度显示
|
||||||
*/
|
*/
|
||||||
import { computed, ref, watch, PropType, Ref, getCurrentInstance, nextTick, watchEffect } from 'vue'
|
import {
|
||||||
import { custom_props, computedTheme, computedClass, computedStyle, computedDark } from '../../tool/lib/minxs'
|
computed,
|
||||||
|
ref,
|
||||||
|
watch,
|
||||||
|
PropType,
|
||||||
|
Ref,
|
||||||
|
getCurrentInstance,
|
||||||
|
nextTick,
|
||||||
|
watchEffect,
|
||||||
|
} from 'vue'
|
||||||
|
import {
|
||||||
|
custom_props,
|
||||||
|
computedTheme,
|
||||||
|
computedClass,
|
||||||
|
computedStyle,
|
||||||
|
computedDark,
|
||||||
|
} from '../../tool/lib/minxs'
|
||||||
import weekDay from './week-day.vue'
|
import weekDay from './week-day.vue'
|
||||||
import monthYear from './month-year.vue'
|
import monthYear from './month-year.vue'
|
||||||
import yearDu from './year-du.vue'
|
import yearDu from './year-du.vue'
|
||||||
@ -149,7 +166,13 @@ import rangeDay from './range-day.vue'
|
|||||||
import monthQuarter from './month-quarter.vue'
|
import monthQuarter from './month-quarter.vue'
|
||||||
import tmSheet from '../tm-sheet/tm-sheet.vue'
|
import tmSheet from '../tm-sheet/tm-sheet.vue'
|
||||||
import * as dayjs from '../../tool/dayjs/esm'
|
import * as dayjs from '../../tool/dayjs/esm'
|
||||||
import { monthDayItem, dateItemStyle, monthYearItem, weekItem, yearItem } from './interface'
|
import {
|
||||||
|
monthDayItem,
|
||||||
|
dateItemStyle,
|
||||||
|
monthYearItem,
|
||||||
|
weekItem,
|
||||||
|
yearItem,
|
||||||
|
} from './interface'
|
||||||
const proxy = getCurrentInstance()?.proxy ?? null
|
const proxy = getCurrentInstance()?.proxy ?? null
|
||||||
const rDay = ref<InstanceType<typeof rangeDay> | null>(null)
|
const rDay = ref<InstanceType<typeof rangeDay> | null>(null)
|
||||||
const Day = ref<InstanceType<typeof monthDay> | null>(null)
|
const Day = ref<InstanceType<typeof monthDay> | null>(null)
|
||||||
@ -163,31 +186,38 @@ const Week = ref<InstanceType<typeof weekDay> | null>(null)
|
|||||||
* click 日期被选中时触发,注意禁用的日期不会触发 。
|
* click 日期被选中时触发,注意禁用的日期不会触发 。
|
||||||
* change 当切换年或者月的时候触发。
|
* change 当切换年或者月的时候触发。
|
||||||
*/
|
*/
|
||||||
const emits = defineEmits(['update:modelValue', 'update:modelStr', 'confirm', 'click', 'change'])
|
const emits = defineEmits([
|
||||||
|
'update:modelValue',
|
||||||
|
'update:modelStr',
|
||||||
|
'confirm',
|
||||||
|
'click',
|
||||||
|
'change',
|
||||||
|
'getDArray',
|
||||||
|
])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
...custom_props,
|
...custom_props,
|
||||||
followTheme: {
|
followTheme: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true,
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 数组
|
* 数组
|
||||||
*/
|
*/
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
type: Array as PropType<Array<String | Number | Date>>,
|
type: Array as PropType<Array<String | Number | Date>>,
|
||||||
default: () => []
|
default: () => [],
|
||||||
},
|
},
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Array as PropType<Array<String | Number | Date>>,
|
type: Array as PropType<Array<String | Number | Date>>,
|
||||||
default: () => []
|
default: () => [],
|
||||||
},
|
},
|
||||||
//单向绑定输入展示日期,此字段用来在页面上展示。只向外输出。
|
//单向绑定输入展示日期,此字段用来在页面上展示。只向外输出。
|
||||||
//功能目的:用来在页面上显示,特别是在input上绑定显示非常方便。
|
//功能目的:用来在页面上显示,特别是在input上绑定显示非常方便。
|
||||||
//标准数据保存时,请使用modelValue保存,而不是此值。
|
//标准数据保存时,请使用modelValue保存,而不是此值。
|
||||||
modelStr: {
|
modelStr: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 日期模式
|
* 日期模式
|
||||||
@ -199,30 +229,32 @@ const props = defineProps({
|
|||||||
* quarter :按季度选择模式。
|
* quarter :按季度选择模式。
|
||||||
*/
|
*/
|
||||||
model: {
|
model: {
|
||||||
type: String as PropType<'quarter' | 'day' | 'month' | 'year' | 'rang' | 'week'>,
|
type: String as PropType<
|
||||||
default: 'day'
|
'quarter' | 'day' | 'month' | 'year' | 'rang' | 'week'
|
||||||
|
>,
|
||||||
|
default: 'day',
|
||||||
},
|
},
|
||||||
color: {
|
color: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'primary'
|
default: 'primary',
|
||||||
},
|
},
|
||||||
linear: {
|
linear: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
linearDeep: {
|
linearDeep: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'light'
|
default: 'light',
|
||||||
},
|
},
|
||||||
//指的是:有效的可选时间,小于此时间,不允许选中。
|
//指的是:有效的可选时间,小于此时间,不允许选中。
|
||||||
start: {
|
start: {
|
||||||
type: [String, Number, Date],
|
type: [String, Number, Date],
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
//指的是:有效的可选时间,大于此时间,不允许选中。
|
//指的是:有效的可选时间,大于此时间,不允许选中。
|
||||||
end: {
|
end: {
|
||||||
type: [String, Number, Date],
|
type: [String, Number, Date],
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 日历组件属性 */
|
/** 日历组件属性 */
|
||||||
@ -231,48 +263,70 @@ const props = defineProps({
|
|||||||
//被禁用的日期将无法选中。
|
//被禁用的日期将无法选中。
|
||||||
disabledDate: {
|
disabledDate: {
|
||||||
type: Array as PropType<Array<String | Number | Date>>,
|
type: Array as PropType<Array<String | Number | Date>>,
|
||||||
default: () => []
|
default: () => [],
|
||||||
},
|
},
|
||||||
//是否允许多选。
|
//是否允许多选。
|
||||||
multiple: {
|
multiple: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
//设定单个日期的样式。
|
//设定单个日期的样式。
|
||||||
dateStyle: {
|
dateStyle: {
|
||||||
type: Array as PropType<Array<dateItemStyle>>,
|
type: Array as PropType<Array<dateItemStyle>>,
|
||||||
default: () => []
|
default: () => [],
|
||||||
},
|
},
|
||||||
//当multiple=true时,可以选择的最大日期数量。
|
//当multiple=true时,可以选择的最大日期数量。
|
||||||
max: {
|
max: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 999
|
default: 999,
|
||||||
},
|
},
|
||||||
/** 日历组件属性结束 */
|
/** 日历组件属性结束 */
|
||||||
//隐藏底部确认按钮
|
//隐藏底部确认按钮
|
||||||
hideButton: {
|
hideButton: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
//隐藏头部操作栏
|
//隐藏头部操作栏
|
||||||
hideTool: {
|
hideTool: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
/**modelStr的格式化输出选项,不会影响value值,只对输出值有效 */
|
/**modelStr的格式化输出选项,不会影响value值,只对输出值有效 */
|
||||||
format: {
|
format: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'YYYY/MM/DD'
|
default: 'YYYY/MM/DD',
|
||||||
},
|
},
|
||||||
confirmText: {
|
confirmText: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '确认'
|
default: '确认',
|
||||||
},
|
},
|
||||||
//周次,本日、本季、本年、本月、本周的文字请按顺序提供文本,方便定义其它语言。
|
//周次,本日、本季、本年、本月、本周的文字请按顺序提供文本,方便定义其它语言。
|
||||||
textUnit: {
|
textUnit: {
|
||||||
type: Array as PropType<string[]>,
|
type: Array as PropType<string[]>,
|
||||||
default: ['周次','一','二','三','四','五','六','日','本日','本周','本月','本季度','本年','月','第${x}季度','年']
|
default: [
|
||||||
}
|
'周次',
|
||||||
|
'一',
|
||||||
|
'二',
|
||||||
|
'三',
|
||||||
|
'四',
|
||||||
|
'五',
|
||||||
|
'六',
|
||||||
|
'日',
|
||||||
|
'本日',
|
||||||
|
'本周',
|
||||||
|
'本月',
|
||||||
|
'本季度',
|
||||||
|
'本年',
|
||||||
|
'月',
|
||||||
|
'第${x}季度',
|
||||||
|
'年',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
showDefault: {
|
||||||
|
//是否显示被选中的默认样式
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
const _value = ref(props.defaultValue)
|
const _value = ref(props.defaultValue)
|
||||||
const _modelType = computed(() => props.model)
|
const _modelType = computed(() => props.model)
|
||||||
@ -281,7 +335,7 @@ const _textUnit = computed(() => props.textUnit)
|
|||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
() => (_value.value = props.modelValue),
|
() => (_value.value = props.modelValue),
|
||||||
{ deep: true }
|
{ deep: true },
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
_value,
|
_value,
|
||||||
@ -290,7 +344,7 @@ watch(
|
|||||||
let fm = fmar.join('~')
|
let fm = fmar.join('~')
|
||||||
emits('update:modelStr', fm)
|
emits('update:modelStr', fm)
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true },
|
||||||
)
|
)
|
||||||
function change(e: Array<string | number>) {
|
function change(e: Array<string | number>) {
|
||||||
emits('change', e)
|
emits('change', e)
|
||||||
@ -331,6 +385,10 @@ defineExpose({
|
|||||||
// mont,year模式下,没有此方法
|
// mont,year模式下,没有此方法
|
||||||
prevMonth: () => {
|
prevMonth: () => {
|
||||||
nextTick(() => getRefs().prevMonth())
|
nextTick(() => getRefs().prevMonth())
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const getDArray = (dArray: Array<String>) => {
|
||||||
|
emits('getDArray', dArray)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -123,7 +123,8 @@ const props = defineProps({
|
|||||||
day: true,
|
day: true,
|
||||||
hour: false,
|
hour: false,
|
||||||
minute: false,
|
minute: false,
|
||||||
second: false
|
second: false,
|
||||||
|
am_pm: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -5,6 +5,7 @@ export interface showDetail {
|
|||||||
hour: boolean,
|
hour: boolean,
|
||||||
minute: boolean,
|
minute: boolean,
|
||||||
second: boolean,
|
second: boolean,
|
||||||
|
am_pm: boolean
|
||||||
}
|
}
|
||||||
export enum timeDetailType {
|
export enum timeDetailType {
|
||||||
year = "year",
|
year = "year",
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="flex relative flex-col" :style="{ height: props.height + 'rpx' }">
|
<view
|
||||||
<view style="display: flex">
|
class="flex relative flex-col"
|
||||||
|
:style="{ height: props.height + 'rpx' }"
|
||||||
|
>
|
||||||
|
<view style="display: flex;">
|
||||||
<picker-view
|
<picker-view
|
||||||
v-if="show"
|
v-if="show"
|
||||||
:value="colIndex"
|
:value="colIndex"
|
||||||
@ -16,7 +19,6 @@
|
|||||||
:key="index"
|
:key="index"
|
||||||
class="flex itemcel flex-row flex-row-center-center"
|
class="flex itemcel flex-row flex-row-center-center"
|
||||||
:class="[colIndex[0] == index ? '' : 'UnitemSelected']"
|
:class="[colIndex[0] == index ? '' : 'UnitemSelected']"
|
||||||
|
|
||||||
>
|
>
|
||||||
<!-- #ifdef APP-NVUE -->
|
<!-- #ifdef APP-NVUE -->
|
||||||
<TmText
|
<TmText
|
||||||
@ -26,9 +28,10 @@
|
|||||||
></TmText>
|
></TmText>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<!-- #ifndef APP-NVUE -->
|
<!-- #ifndef APP-NVUE -->
|
||||||
<text :style="{color:store.tmStore.dark?'white':'black'}">{{item + showSuffix['year']}}</text>
|
<text :style="{ color: store.tmStore.dark ? 'white' : 'black' }">
|
||||||
|
{{ item + showSuffix['year'] }}
|
||||||
|
</text>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</picker-view-column>
|
</picker-view-column>
|
||||||
<picker-view-column v-if="showCol.month">
|
<picker-view-column v-if="showCol.month">
|
||||||
@ -38,7 +41,6 @@
|
|||||||
class="flex itemcel flex-row flex-row-center-center"
|
class="flex itemcel flex-row flex-row-center-center"
|
||||||
:class="[colIndex[1] == index ? '' : 'UnitemSelected']"
|
:class="[colIndex[1] == index ? '' : 'UnitemSelected']"
|
||||||
>
|
>
|
||||||
|
|
||||||
<!-- #ifdef APP-NVUE -->
|
<!-- #ifdef APP-NVUE -->
|
||||||
<TmText
|
<TmText
|
||||||
:font-size="30"
|
:font-size="30"
|
||||||
@ -47,9 +49,10 @@
|
|||||||
></TmText>
|
></TmText>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<!-- #ifndef APP-NVUE -->
|
<!-- #ifndef APP-NVUE -->
|
||||||
<text :style="{color:store.tmStore.dark?'white':'black'}">{{item + 1 + showSuffix['month']}}</text>
|
<text :style="{ color: store.tmStore.dark ? 'white' : 'black' }">
|
||||||
|
{{ item + 1 + showSuffix['month'] }}
|
||||||
|
</text>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</picker-view-column>
|
</picker-view-column>
|
||||||
<picker-view-column v-if="showCol.day">
|
<picker-view-column v-if="showCol.day">
|
||||||
@ -59,7 +62,6 @@
|
|||||||
class="flex itemcel flex-row flex-row-center-center"
|
class="flex itemcel flex-row flex-row-center-center"
|
||||||
:class="[colIndex[2] == index ? '' : 'UnitemSelected']"
|
:class="[colIndex[2] == index ? '' : 'UnitemSelected']"
|
||||||
>
|
>
|
||||||
|
|
||||||
<!-- #ifdef APP-NVUE -->
|
<!-- #ifdef APP-NVUE -->
|
||||||
<TmText
|
<TmText
|
||||||
:font-size="30"
|
:font-size="30"
|
||||||
@ -68,7 +70,9 @@
|
|||||||
></TmText>
|
></TmText>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<!-- #ifndef APP-NVUE -->
|
<!-- #ifndef APP-NVUE -->
|
||||||
<text :style="{color:store.tmStore.dark?'white':'black'}">{{item + showSuffix['date']}}</text>
|
<text :style="{ color: store.tmStore.dark ? 'white' : 'black' }">
|
||||||
|
{{ item + showSuffix['date'] }}
|
||||||
|
</text>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
</view>
|
</view>
|
||||||
</picker-view-column>
|
</picker-view-column>
|
||||||
@ -79,7 +83,6 @@
|
|||||||
class="flex itemcel flex-row flex-row-center-center"
|
class="flex itemcel flex-row flex-row-center-center"
|
||||||
:class="[colIndex[3] == index ? '' : 'UnitemSelected']"
|
:class="[colIndex[3] == index ? '' : 'UnitemSelected']"
|
||||||
>
|
>
|
||||||
|
|
||||||
<!-- #ifdef APP-NVUE -->
|
<!-- #ifdef APP-NVUE -->
|
||||||
<TmText
|
<TmText
|
||||||
:font-size="30"
|
:font-size="30"
|
||||||
@ -88,7 +91,9 @@
|
|||||||
></TmText>
|
></TmText>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<!-- #ifndef APP-NVUE -->
|
<!-- #ifndef APP-NVUE -->
|
||||||
<text :style="{color:store.tmStore.dark?'white':'black'}">{{item + showSuffix['hour']}}</text>
|
<text :style="{ color: store.tmStore.dark ? 'white' : 'black' }">
|
||||||
|
{{ item + showSuffix['hour'] }}
|
||||||
|
</text>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
</view>
|
</view>
|
||||||
</picker-view-column>
|
</picker-view-column>
|
||||||
@ -99,7 +104,6 @@
|
|||||||
class="flex itemcel flex-row flex-row-center-center"
|
class="flex itemcel flex-row flex-row-center-center"
|
||||||
:class="[colIndex[4] == index ? '' : 'UnitemSelected']"
|
:class="[colIndex[4] == index ? '' : 'UnitemSelected']"
|
||||||
>
|
>
|
||||||
|
|
||||||
<!-- #ifdef APP-NVUE -->
|
<!-- #ifdef APP-NVUE -->
|
||||||
<TmText
|
<TmText
|
||||||
:font-size="30"
|
:font-size="30"
|
||||||
@ -108,7 +112,9 @@
|
|||||||
></TmText>
|
></TmText>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<!-- #ifndef APP-NVUE -->
|
<!-- #ifndef APP-NVUE -->
|
||||||
<text :style="{color:store.tmStore.dark?'white':'black'}">{{item + showSuffix['minute']}}</text>
|
<text :style="{ color: store.tmStore.dark ? 'white' : 'black' }">
|
||||||
|
{{ item + showSuffix['minute'] }}
|
||||||
|
</text>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
</view>
|
</view>
|
||||||
</picker-view-column>
|
</picker-view-column>
|
||||||
@ -119,7 +125,6 @@
|
|||||||
class="flex itemcel flex-row flex-row-center-center"
|
class="flex itemcel flex-row flex-row-center-center"
|
||||||
:class="[colIndex[5] == index ? '' : 'UnitemSelected']"
|
:class="[colIndex[5] == index ? '' : 'UnitemSelected']"
|
||||||
>
|
>
|
||||||
|
|
||||||
<!-- #ifdef APP-NVUE -->
|
<!-- #ifdef APP-NVUE -->
|
||||||
<TmText
|
<TmText
|
||||||
:font-size="30"
|
:font-size="30"
|
||||||
@ -128,7 +133,9 @@
|
|||||||
></TmText>
|
></TmText>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<!-- #ifndef APP-NVUE -->
|
<!-- #ifndef APP-NVUE -->
|
||||||
<text :style="{color:store.tmStore.dark?'white':'black'}">{{item + showSuffix['second']}}</text>
|
<text :style="{ color: store.tmStore.dark ? 'white' : 'black' }">
|
||||||
|
{{ item + showSuffix['second'] }}
|
||||||
|
</text>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
</view>
|
</view>
|
||||||
</picker-view-column>
|
</picker-view-column>
|
||||||
@ -136,19 +143,24 @@
|
|||||||
<picker-view
|
<picker-view
|
||||||
:value="ampmIndex"
|
:value="ampmIndex"
|
||||||
@change="change1"
|
@change="change1"
|
||||||
:style="{ height: props.height + 'rpx',width: `${100/(trueCount+1)}%` }"
|
:style="{
|
||||||
|
height: props.height + 'rpx',
|
||||||
|
width: `${100 / (trueCount + 1)}%`,
|
||||||
|
}"
|
||||||
:mask-style="maskStyle"
|
:mask-style="maskStyle"
|
||||||
:immediateChange="props.immediateChange"
|
:immediateChange="props.immediateChange"
|
||||||
indicator-style="height:50px"
|
indicator-style="height:50px"
|
||||||
|
v-if="showCol.am_pm"
|
||||||
>
|
>
|
||||||
<picker-view-column>
|
<picker-view-column v-if="showCol.am_pm">
|
||||||
<view
|
<view
|
||||||
v-for="(item, index) in ['上午', '下午']"
|
v-for="(item, index) in ['上午', '下午']"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="flex itemcel flex-row flex-row-center-center"
|
class="flex itemcel flex-row flex-row-center-center"
|
||||||
>
|
>
|
||||||
|
<text :style="{ color: store.tmStore.dark ? 'white' : 'black' }">
|
||||||
<text :style="{color:store.tmStore.dark?'white':'black'}">{{item}}</text>
|
{{ item }}
|
||||||
|
</text>
|
||||||
</view>
|
</view>
|
||||||
</picker-view-column>
|
</picker-view-column>
|
||||||
</picker-view>
|
</picker-view>
|
||||||
@ -177,7 +189,7 @@
|
|||||||
* 时间选择
|
* 时间选择
|
||||||
* @description 嵌入在页面的时间选择器。
|
* @description 嵌入在页面的时间选择器。
|
||||||
*/
|
*/
|
||||||
import { useTmpiniaStore } from "../../tool/lib/tmpinia";
|
import { useTmpiniaStore } from '../../tool/lib/tmpinia'
|
||||||
import {
|
import {
|
||||||
computed,
|
computed,
|
||||||
PropType,
|
PropType,
|
||||||
@ -189,44 +201,44 @@ import {
|
|||||||
watch,
|
watch,
|
||||||
onUpdated,
|
onUpdated,
|
||||||
Ref,
|
Ref,
|
||||||
} from "vue";
|
} from 'vue'
|
||||||
import { showDetail, coltimeData, timeDetailType } from "./interface";
|
import { showDetail, coltimeData, timeDetailType } from './interface'
|
||||||
import * as dayjs from "../../tool/dayjs/esm";
|
import * as dayjs from '../../tool/dayjs/esm'
|
||||||
import { propsOpts } from "./props";
|
import { propsOpts } from './props'
|
||||||
import {
|
import {
|
||||||
rangeTimeArray,
|
rangeTimeArray,
|
||||||
getNowbyIndex,
|
getNowbyIndex,
|
||||||
getIndexNowbydate,
|
getIndexNowbydate,
|
||||||
checkNowDateisBetween,
|
checkNowDateisBetween,
|
||||||
} from "./time";
|
} from './time'
|
||||||
import TmText from "../tm-text/tm-text.vue";
|
import TmText from '../tm-text/tm-text.vue'
|
||||||
import TmIcon from "../tm-icon/tm-icon.vue";
|
import TmIcon from '../tm-icon/tm-icon.vue'
|
||||||
// #ifdef APP-PLUS-NVUE
|
// #ifdef APP-PLUS-NVUE
|
||||||
const dom = uni.requireNativePlugin("dom");
|
const dom = uni.requireNativePlugin('dom')
|
||||||
// #endif
|
// #endif
|
||||||
const proxy = getCurrentInstance()?.proxy ?? null;
|
const proxy = getCurrentInstance()?.proxy ?? null
|
||||||
const store = useTmpiniaStore();
|
const store = useTmpiniaStore()
|
||||||
const emits = defineEmits(["update:modelValue", "update:modelStr", "change"]);
|
const emits = defineEmits(['update:modelValue', 'update:modelStr', 'change'])
|
||||||
const tmTimeViewName = "tmTimeViewName";
|
const tmTimeViewName = 'tmTimeViewName'
|
||||||
const DayJs = dayjs.default;
|
const DayJs = dayjs.default
|
||||||
const props = defineProps({ ...propsOpts });
|
const props = defineProps({ ...propsOpts })
|
||||||
const _nowtime = ref(
|
const _nowtime = ref(
|
||||||
DayJs(checkNowDateisBetween(props.defaultValue, props.start, props.end))
|
DayJs(checkNowDateisBetween(props.defaultValue, props.start, props.end)),
|
||||||
);
|
)
|
||||||
const _nowtimeValue = computed(() => _nowtime.value.format());
|
const _nowtimeValue = computed(() => _nowtime.value.format())
|
||||||
|
|
||||||
const show = ref(true);
|
const show = ref(true)
|
||||||
|
|
||||||
const _startTime = computed(() => {
|
const _startTime = computed(() => {
|
||||||
return DayJs(props.start).isValid()
|
return DayJs(props.start).isValid()
|
||||||
? DayJs(props.start).format()
|
? DayJs(props.start).format()
|
||||||
: DayJs().subtract(3, "year").format();
|
: DayJs().subtract(3, 'year').format()
|
||||||
});
|
})
|
||||||
const _endTime = computed(() => {
|
const _endTime = computed(() => {
|
||||||
return DayJs(props.end).isValid()
|
return DayJs(props.end).isValid()
|
||||||
? DayJs(props.end).format()
|
? DayJs(props.end).format()
|
||||||
: DayJs().add(1, "year").format();
|
: DayJs().add(1, 'year').format()
|
||||||
});
|
})
|
||||||
const showCol = computed<showDetail>(() => {
|
const showCol = computed<showDetail>(() => {
|
||||||
return {
|
return {
|
||||||
year: props.showDetail?.year ?? true,
|
year: props.showDetail?.year ?? true,
|
||||||
@ -235,24 +247,25 @@ const showCol = computed<showDetail>(() => {
|
|||||||
hour: props.showDetail?.hour ?? false,
|
hour: props.showDetail?.hour ?? false,
|
||||||
minute: props.showDetail?.minute ?? false,
|
minute: props.showDetail?.minute ?? false,
|
||||||
second: props.showDetail?.second ?? false,
|
second: props.showDetail?.second ?? false,
|
||||||
};
|
am_pm: props.showDetail?.am_pm ?? true,
|
||||||
});
|
}
|
||||||
|
})
|
||||||
const trueCount = computed(() => {
|
const trueCount = computed(() => {
|
||||||
return Object.values(showCol.value).filter(value => value === true).length;
|
return Object.values(showCol.value).filter((value) => value === true).length
|
||||||
});
|
})
|
||||||
const showSuffix = computed(() => {
|
const showSuffix = computed(() => {
|
||||||
return {
|
return {
|
||||||
year: props.showSuffix?.year ?? "年",
|
year: props.showSuffix?.year ?? '年',
|
||||||
month: props.showSuffix?.month ?? "月",
|
month: props.showSuffix?.month ?? '月',
|
||||||
hour: props.showSuffix?.hour ?? "时",
|
hour: props.showSuffix?.hour ?? '时',
|
||||||
minute: props.showSuffix?.minute ?? "分",
|
minute: props.showSuffix?.minute ?? '分',
|
||||||
second: props.showSuffix?.second ?? "秒",
|
second: props.showSuffix?.second ?? '秒',
|
||||||
date: props.showSuffix?.day ?? "日",
|
date: props.showSuffix?.day ?? '日',
|
||||||
};
|
}
|
||||||
});
|
})
|
||||||
const isDark = computed(() => store.tmStore.dark);
|
const isDark = computed(() => store.tmStore.dark)
|
||||||
let colIndex: Ref<Array<number>> = ref([0, 0, 0, 0, 0, 0]);
|
let colIndex: Ref<Array<number>> = ref([0, 0, 0, 0, 0, 0])
|
||||||
let ampmIndex: Ref<Array<number>> = ref([0]);
|
let ampmIndex: Ref<Array<number>> = ref([0])
|
||||||
const _col = ref({
|
const _col = ref({
|
||||||
year: [] as Array<number>,
|
year: [] as Array<number>,
|
||||||
month: [] as Array<number>,
|
month: [] as Array<number>,
|
||||||
@ -260,129 +273,144 @@ const _col = ref({
|
|||||||
hour: [] as Array<number>,
|
hour: [] as Array<number>,
|
||||||
minute: [] as Array<number>,
|
minute: [] as Array<number>,
|
||||||
second: [] as Array<number>,
|
second: [] as Array<number>,
|
||||||
});
|
})
|
||||||
|
|
||||||
let timid = NaN;
|
let timid = NaN
|
||||||
const maskWidth = ref(0);
|
const maskWidth = ref(0)
|
||||||
const maskHeight = computed(() => {
|
const maskHeight = computed(() => {
|
||||||
return (uni.upx2px(props.height) - 50) / 2;
|
return (uni.upx2px(props.height) - 50) / 2
|
||||||
});
|
})
|
||||||
const maskStyle = computed(() => {
|
const maskStyle = computed(() => {
|
||||||
let str_white =
|
let str_white =
|
||||||
"background-image:linear-gradient(rgba(255,255,255,0.95),rgba(255,255,255,0.6)),linear-gradient(rgba(255,255,255,0.6),rgba(255,255,255,0.95))";
|
'background-image:linear-gradient(rgba(255,255,255,0.95),rgba(255,255,255,0.6)),linear-gradient(rgba(255,255,255,0.6),rgba(255,255,255,0.95))'
|
||||||
let str_black =
|
let str_black =
|
||||||
"background-image:linear-gradient(rgba(17, 17, 17, 1.0),rgba(106, 106, 106, 0.2)),linear-gradient(rgba(106, 106, 106, 0.2),rgba(17, 17, 17, 1.0))";
|
'background-image:linear-gradient(rgba(17, 17, 17, 1.0),rgba(106, 106, 106, 0.2)),linear-gradient(rgba(106, 106, 106, 0.2),rgba(17, 17, 17, 1.0))'
|
||||||
|
|
||||||
// #ifdef APP-NVUE
|
// #ifdef APP-NVUE
|
||||||
str_black =
|
str_black =
|
||||||
"background-image: linear-gradient(to bottom,rgba(30, 30, 30, 0.9),rgba(104, 104, 104, 0.6))";
|
'background-image: linear-gradient(to bottom,rgba(30, 30, 30, 0.9),rgba(104, 104, 104, 0.6))'
|
||||||
// #endif
|
// #endif
|
||||||
if (!isDark.value) {
|
if (!isDark.value) {
|
||||||
return str_white;
|
return str_white
|
||||||
}
|
}
|
||||||
return str_black;
|
return str_black
|
||||||
});
|
})
|
||||||
_col.value = rangeTimeArray(
|
_col.value = rangeTimeArray(
|
||||||
_nowtimeValue.value,
|
_nowtimeValue.value,
|
||||||
_startTime.value,
|
_startTime.value,
|
||||||
_endTime.value,
|
_endTime.value,
|
||||||
showCol.value
|
showCol.value,
|
||||||
);
|
)
|
||||||
function change1(data) {
|
function change1(data) {
|
||||||
console.log('data', data)
|
console.log('data', data)
|
||||||
}
|
}
|
||||||
function colchange(e: any) {
|
function colchange(e: any) {
|
||||||
|
let changedate = getNowbyIndex(
|
||||||
let changedate = getNowbyIndex(_col.value, e.detail.value, showCol.value, _startTime.value,_endTime.value);
|
_col.value,
|
||||||
let testDate = checkNowDateisBetween(changedate, _startTime.value,_endTime.value)
|
e.detail.value,
|
||||||
|
showCol.value,
|
||||||
|
_startTime.value,
|
||||||
|
_endTime.value,
|
||||||
|
)
|
||||||
|
let testDate = checkNowDateisBetween(
|
||||||
|
changedate,
|
||||||
|
_startTime.value,
|
||||||
|
_endTime.value,
|
||||||
|
)
|
||||||
|
|
||||||
let testRang = rangeTimeArray(
|
let testRang = rangeTimeArray(
|
||||||
testDate,
|
testDate,
|
||||||
_startTime.value,
|
_startTime.value,
|
||||||
_endTime.value,
|
_endTime.value,
|
||||||
showCol.value
|
showCol.value,
|
||||||
);
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_nowtime.value = DayJs(testDate);
|
|
||||||
colIndex.value = getIndexNowbydate(testRang, _nowtime.value, showCol.value);
|
|
||||||
emits("update:modelValue", _nowtime.value.format("YYYY/MM/DD HH:mm:ss"));
|
|
||||||
emits("update:modelStr", _nowtime.value.format(props.format));
|
|
||||||
emits("change", _nowtime.value.format(props.format));
|
|
||||||
|
|
||||||
_col.value= testRang;
|
|
||||||
|
|
||||||
|
_nowtime.value = DayJs(testDate)
|
||||||
|
colIndex.value = getIndexNowbydate(testRang, _nowtime.value, showCol.value)
|
||||||
|
emits('update:modelValue', _nowtime.value.format('YYYY/MM/DD HH:mm:ss'))
|
||||||
|
emits('update:modelStr', _nowtime.value.format(props.format))
|
||||||
|
emits('change', _nowtime.value.format(props.format))
|
||||||
|
|
||||||
|
_col.value = testRang
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
() => {
|
() => {
|
||||||
if (!DayJs(props.modelValue).isValid()) return;
|
if (!DayJs(props.modelValue).isValid()) return
|
||||||
let deattime = DayJs(checkNowDateisBetween(props.modelValue, props.start, props.end));
|
let deattime = DayJs(
|
||||||
|
checkNowDateisBetween(props.modelValue, props.start, props.end),
|
||||||
|
)
|
||||||
|
|
||||||
if (DayJs(deattime).isSame(_nowtime.value)) return;
|
if (DayJs(deattime).isSame(_nowtime.value)) return
|
||||||
_nowtime.value = deattime;
|
_nowtime.value = deattime
|
||||||
emits("update:modelStr", _nowtime.value.format(props.format));
|
emits('update:modelStr', _nowtime.value.format(props.format))
|
||||||
// #ifdef APP-NVUE
|
// #ifdef APP-NVUE
|
||||||
_col.value = rangeTimeArray(
|
_col.value = rangeTimeArray(
|
||||||
deattime,
|
deattime,
|
||||||
_startTime.value,
|
_startTime.value,
|
||||||
_endTime.value,
|
_endTime.value,
|
||||||
showCol.value
|
showCol.value,
|
||||||
);
|
)
|
||||||
show.value = false;
|
show.value = false
|
||||||
colIndex.value = getIndexNowbydate(_col.value, _nowtime.value, showCol.value);
|
colIndex.value = getIndexNowbydate(
|
||||||
|
_col.value,
|
||||||
|
_nowtime.value,
|
||||||
|
showCol.value,
|
||||||
|
)
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
/**这力着重解释下,uni sdk从3.6.8开始,在nvue下直接对picker view赋值value,页面不会有任何变化,必须刷新下页面才可以显示正确
|
/**这力着重解释下,uni sdk从3.6.8开始,在nvue下直接对picker view赋值value,页面不会有任何变化,必须刷新下页面才可以显示正确
|
||||||
* 其它平台没有这问题
|
* 其它平台没有这问题
|
||||||
*/
|
*/
|
||||||
show.value = true;
|
show.value = true
|
||||||
});
|
})
|
||||||
// #endif
|
// #endif
|
||||||
// #ifndef APP-NVUE
|
// #ifndef APP-NVUE
|
||||||
_col.value = rangeTimeArray(
|
_col.value = rangeTimeArray(
|
||||||
deattime,
|
deattime,
|
||||||
_startTime.value,
|
_startTime.value,
|
||||||
_endTime.value,
|
_endTime.value,
|
||||||
showCol.value
|
showCol.value,
|
||||||
);
|
)
|
||||||
colIndex.value = getIndexNowbydate(_col.value, _nowtime.value, showCol.value);
|
colIndex.value = getIndexNowbydate(
|
||||||
|
_col.value,
|
||||||
|
_nowtime.value,
|
||||||
|
showCol.value,
|
||||||
|
)
|
||||||
// #endif
|
// #endif
|
||||||
}
|
},
|
||||||
);
|
)
|
||||||
|
|
||||||
function nvuegetClientRect() {
|
function nvuegetClientRect() {
|
||||||
nextTick(function () {
|
nextTick(function () {
|
||||||
// #ifdef APP-PLUS-NVUE
|
// #ifdef APP-PLUS-NVUE
|
||||||
dom.getComponentRect(proxy.$refs.picker, function (res) {
|
dom.getComponentRect(proxy.$refs.picker, function (res) {
|
||||||
if (res?.size) {
|
if (res?.size) {
|
||||||
maskWidth.value = res.size.width;
|
maskWidth.value = res.size.width
|
||||||
|
|
||||||
if (res.size.width == 0) {
|
if (res.size.width == 0) {
|
||||||
nvuegetClientRect();
|
nvuegetClientRect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
// #endif
|
// #endif
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
nvuegetClientRect();
|
nvuegetClientRect()
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
emits("update:modelValue", _nowtime.value.format("YYYY/MM/DD HH:mm:ss"));
|
emits('update:modelValue', _nowtime.value.format('YYYY/MM/DD HH:mm:ss'))
|
||||||
emits("update:modelStr", _nowtime.value.format(props.format));
|
emits('update:modelStr', _nowtime.value.format(props.format))
|
||||||
colIndex.value = getIndexNowbydate(_col.value, _nowtime.value, showCol.value);
|
colIndex.value = getIndexNowbydate(
|
||||||
});
|
_col.value,
|
||||||
});
|
_nowtime.value,
|
||||||
|
showCol.value,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
onUpdated(() => nvuegetClientRect())
|
||||||
onUpdated(() => nvuegetClientRect());
|
|
||||||
|
|
||||||
// defineExpose({tmTimeViewName,setNowtime})
|
// defineExpose({tmTimeViewName,setNowtime})
|
||||||
</script>
|
</script>
|
||||||
@ -397,7 +425,11 @@ onUpdated(() => nvuegetClientRect());
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bottom {
|
.bottom {
|
||||||
background-image: linear-gradient(to top, rgba(17, 17, 17, 1), rgba(36, 36, 36, 0.6));
|
background-image: linear-gradient(
|
||||||
|
to top,
|
||||||
|
rgba(17, 17, 17, 1),
|
||||||
|
rgba(36, 36, 36, 0.6)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
.itemcel {
|
.itemcel {
|
||||||
|
@ -72,5 +72,49 @@
|
|||||||
"message.action.text": "进行注销操作",
|
"message.action.text": "进行注销操作",
|
||||||
"index.mine.upload": "点击上传",
|
"index.mine.upload": "点击上传",
|
||||||
"index.mine.reUpload": "重新上传",
|
"index.mine.reUpload": "重新上传",
|
||||||
"index.mine.loading":"载入中"
|
"index.mine.loading": "载入中",
|
||||||
|
"cancel": "取消",
|
||||||
|
"search.hint": "检索您要查找的内容吧~",
|
||||||
|
"search.chat.count": "条相关聊天记录",
|
||||||
|
"index.mine.project": "项目",
|
||||||
|
"chat.type.group": "群聊",
|
||||||
|
"chat.type.record": "聊天记录",
|
||||||
|
"search.result.include": "包含:",
|
||||||
|
"has_more": "更多",
|
||||||
|
"index.type.company": "公司",
|
||||||
|
"search.result.relevant": "相关",
|
||||||
|
"index.chat.settings": "聊天设置",
|
||||||
|
"chat.settings.clearChatRecord": "清空聊天记录",
|
||||||
|
"chat.settings.groupName": "群名称",
|
||||||
|
"chat.settings.groupNotice": "群公告",
|
||||||
|
"chat.settings.groupType": "群类型",
|
||||||
|
"chat.settings.topSession": "置顶会话",
|
||||||
|
"chat.settings.messageNoDisturb": "消息免打扰",
|
||||||
|
"chat.settings.groupGag": "群内禁言",
|
||||||
|
"chat.settings.groupAdmin": "群管理员",
|
||||||
|
"chat.settings.groupMember": "群成员",
|
||||||
|
"search.chat.record": "搜索聊天记录",
|
||||||
|
"record.searchType.date": "日期",
|
||||||
|
"record.searchType.imgAndVideo": "图片及视频",
|
||||||
|
"record.searchType.files": "文件",
|
||||||
|
"record.searchType.link": "链接",
|
||||||
|
"group.identify.admin": "管理员",
|
||||||
|
"group.disband.btn": "解散该群",
|
||||||
|
"group.quit.btn": "退出群聊",
|
||||||
|
"search.condition.date": "按日期查找",
|
||||||
|
"search.condition.date_pickerTitle": "请选择聊天日期",
|
||||||
|
"button.text.done": "完成",
|
||||||
|
"input.placeholder.enter": "请输入...",
|
||||||
|
"chat.settings.editGroupName": "修改群名称",
|
||||||
|
"edit.groupName.placeholder": "请输入群名称(1~20个字)",
|
||||||
|
"chat.settings.editAvatar": "修改头像",
|
||||||
|
"button.text.edit": "修改",
|
||||||
|
"chat.manage.silenceMember": "被禁言的成员",
|
||||||
|
"chat.manage.silenceAll": "全员禁言",
|
||||||
|
"chat.manage.silenceAllHint": "开启后,只允许群管理员发言",
|
||||||
|
"chat.manage.addSilenceMember": "添加禁言成员",
|
||||||
|
"chatSettings.btn.undoSilence": "解禁",
|
||||||
|
"silence.tag.hasDone": "已禁言",
|
||||||
|
"chat.manage.addAdmin": "添加管理员",
|
||||||
|
"search.condition.member": "按群成员查找"
|
||||||
}
|
}
|
||||||
|