Compare commits
12 Commits
yitiji
...
db9707e866
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db9707e866 | ||
|
|
eb324ceada | ||
| aca5727878 | |||
| 12a3668b7f | |||
| 96e7b9b1e2 | |||
|
|
5046e7467f | ||
|
|
23a286cb64 | ||
|
|
c43c0592c6 | ||
| cb83a3269e | |||
| f2f802b73a | |||
|
|
4078f2e543 | ||
|
|
94439fddaa |
@@ -1,15 +1,6 @@
|
||||
<template>
|
||||
<view v-if="show" class="filter-container">
|
||||
<!-- 头部 -->
|
||||
<!-- <view class="filter-header">
|
||||
<text class="back-btn" @click="handleClose">
|
||||
<uni-icons type="left" size="24"></uni-icons>
|
||||
</text>
|
||||
<text class="filter-title">喀什智慧就业平台</text>
|
||||
<view class="back-btn"></view>
|
||||
</view> -->
|
||||
|
||||
<!-- 标签页 -->
|
||||
<!-- 左侧标签页 -->
|
||||
<view class="filter-tabs">
|
||||
<view
|
||||
v-for="(tab, index) in tabs"
|
||||
@@ -22,85 +13,106 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<view class="filter-content">
|
||||
<!-- 学历要求 -->
|
||||
<view v-if="activeTab === 'education'" class="content-section">
|
||||
<radio-group @change="(e) => handleSelect('education', e)">
|
||||
<label
|
||||
v-for="option in educationOptions"
|
||||
:key="option.value"
|
||||
class="radio-item"
|
||||
:class="{ checked: selectedValues['education'] === String(option.value) }"
|
||||
>
|
||||
<radio
|
||||
:value="String(option.value)"
|
||||
:checked="selectedValues['education'] === String(option.value)"
|
||||
/>
|
||||
<text class="option-label">{{ option.label }}</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
<!-- 右侧内容区域 -->
|
||||
<view class="filter-right">
|
||||
<!-- 内容区域 -->
|
||||
<view class="filter-content">
|
||||
<!-- 学历要求 -->
|
||||
<view v-if="activeTab === 'education'" class="content-section">
|
||||
<radio-group @change="(e) => handleSelect('education', e)">
|
||||
<label
|
||||
v-for="option in educationOptions"
|
||||
:key="option.value"
|
||||
class="radio-item"
|
||||
:class="{ checked: selectedValues['education'] === String(option.value) }"
|
||||
>
|
||||
<radio
|
||||
:value="String(option.value)"
|
||||
:checked="selectedValues['education'] === String(option.value)"
|
||||
/>
|
||||
<text class="option-label">{{ option.label }}</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
<!-- 工作经验 -->
|
||||
<view v-if="activeTab === 'experience'" class="content-section">
|
||||
<radio-group @change="(e) => handleSelect('experience', e)">
|
||||
<label
|
||||
v-for="option in experienceOptions"
|
||||
:key="option.value"
|
||||
class="radio-item"
|
||||
:class="{ checked: selectedValues['experience'] === String(option.value) }"
|
||||
>
|
||||
<radio
|
||||
:value="String(option.value)"
|
||||
:checked="selectedValues['experience'] === String(option.value)"
|
||||
/>
|
||||
<text class="option-label">{{ option.label }}</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
<!-- 公司规模 -->
|
||||
<view v-if="activeTab === 'scale'" class="content-section">
|
||||
<radio-group @change="(e) => handleSelect('scale', e)">
|
||||
<label
|
||||
v-for="option in scaleOptions"
|
||||
:key="option.value"
|
||||
class="radio-item"
|
||||
:class="{ checked: selectedValues['scale'] === String(option.value) }"
|
||||
>
|
||||
<radio
|
||||
:value="String(option.value)"
|
||||
:checked="selectedValues['scale'] === String(option.value)"
|
||||
/>
|
||||
<text class="option-label">{{ option.label }}</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
<!-- 地区 -->
|
||||
<view v-if="activeTab === 'area'" class="content-section">
|
||||
<radio-group @change="(e) => handleSelect('area', e)">
|
||||
<label
|
||||
v-for="option in areaOptions"
|
||||
:key="option.value"
|
||||
class="radio-item"
|
||||
:class="{ checked: selectedValues['area'] === String(option.value) }"
|
||||
>
|
||||
<radio
|
||||
:value="String(option.value)"
|
||||
:checked="selectedValues['area'] === String(option.value)"
|
||||
/>
|
||||
<text class="option-label">{{ option.label }}</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
<!-- 岗位类型 -->
|
||||
<view v-if="activeTab === 'jobType'" class="content-section">
|
||||
<radio-group @change="(e) => handleSelect('jobType', e)">
|
||||
<label
|
||||
v-for="option in jobTypeOptions"
|
||||
:key="option.value"
|
||||
class="radio-item"
|
||||
:class="{ checked: selectedValues['jobType'] === String(option.value) }"
|
||||
>
|
||||
<radio
|
||||
:value="String(option.value)"
|
||||
:checked="selectedValues['jobType'] === String(option.value)"
|
||||
/>
|
||||
<text class="option-label">{{ option.label }}</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 工作经验 -->
|
||||
<view v-if="activeTab === 'experience'" class="content-section">
|
||||
<radio-group @change="(e) => handleSelect('experience', e)">
|
||||
<label
|
||||
v-for="option in experienceOptions"
|
||||
:key="option.value"
|
||||
class="radio-item"
|
||||
:class="{ checked: selectedValues['experience'] === String(option.value) }"
|
||||
>
|
||||
<radio
|
||||
:value="String(option.value)"
|
||||
:checked="selectedValues['experience'] === String(option.value)"
|
||||
/>
|
||||
<text class="option-label">{{ option.label }}</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
<!-- 底部按钮 -->
|
||||
<view class="filter-footer">
|
||||
<button class="footer-btn clear-btn" @click="handleClear">清除</button>
|
||||
<button class="footer-btn confirm-btn" @click="handleConfirm">确认</button>
|
||||
</view>
|
||||
|
||||
<!-- 公司规模 -->
|
||||
<view v-if="activeTab === 'scale'" class="content-section">
|
||||
<radio-group @change="(e) => handleSelect('scale', e)">
|
||||
<label
|
||||
v-for="option in scaleOptions"
|
||||
:key="option.value"
|
||||
class="radio-item"
|
||||
:class="{ checked: selectedValues['scale'] === String(option.value) }"
|
||||
>
|
||||
<radio
|
||||
:value="String(option.value)"
|
||||
:checked="selectedValues['scale'] === String(option.value)"
|
||||
/>
|
||||
<text class="option-label">{{ option.label }}</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
<!-- 岗位类型 -->
|
||||
<view v-if="activeTab === 'jobType'" class="content-section">
|
||||
<radio-group @change="(e) => handleSelect('jobType', e)">
|
||||
<label
|
||||
v-for="option in jobTypeOptions"
|
||||
:key="option.value"
|
||||
class="radio-item"
|
||||
:class="{ checked: selectedValues['jobType'] === String(option.value) }"
|
||||
>
|
||||
<radio
|
||||
:value="String(option.value)"
|
||||
:checked="selectedValues['jobType'] === String(option.value)"
|
||||
/>
|
||||
<text class="option-label">{{ option.label }}</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<view class="filter-footer">
|
||||
<button class="footer-btn clear-btn" @click="handleClear">清除</button>
|
||||
<button class="footer-btn confirm-btn" @click="handleConfirm">确认</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -108,7 +120,8 @@
|
||||
<script setup>
|
||||
import { ref, reactive, onBeforeMount } from 'vue';
|
||||
import useDictStore from '@/stores/useDictStore';
|
||||
const { getTransformChildren } = useDictStore();
|
||||
const dictStore = useDictStore();
|
||||
const { getTransformChildren } = dictStore;
|
||||
|
||||
const props = defineProps({
|
||||
show: Boolean,
|
||||
@@ -131,7 +144,8 @@ const tabs = [
|
||||
{ key: 'education', label: '学历要求' },
|
||||
{ key: 'experience', label: '工作经验' },
|
||||
{ key: 'scale', label: '公司规模' },
|
||||
{ key: 'jobType', label: '岗位类型' }
|
||||
{ key: 'jobType', label: '岗位类型' },
|
||||
{ key: 'area', label: '地区' }
|
||||
];
|
||||
|
||||
// 当前激活的标签
|
||||
@@ -142,6 +156,7 @@ const selectedValues = reactive({
|
||||
education: '',
|
||||
experience: '',
|
||||
scale: '',
|
||||
area: '',
|
||||
jobType: ''
|
||||
});
|
||||
|
||||
@@ -149,14 +164,28 @@ const selectedValues = reactive({
|
||||
const educationOptions = ref([]);
|
||||
const experienceOptions = ref([]);
|
||||
const scaleOptions = ref([]);
|
||||
const areaOptions = ref([]);
|
||||
const jobTypeOptions = ref([]);
|
||||
|
||||
// 加载状态
|
||||
const loading = ref(true);
|
||||
|
||||
// 初始化获取数据
|
||||
onBeforeMount(() => {
|
||||
educationOptions.value = getTransformChildren('education', '学历要求').options || [];
|
||||
experienceOptions.value = getTransformChildren('experience', '工作经验').options || [];
|
||||
scaleOptions.value = getTransformChildren('scale', '公司规模').options || [];
|
||||
jobTypeOptions.value = getJobTypeData();
|
||||
onBeforeMount(async () => {
|
||||
try {
|
||||
// 先获取字典数据
|
||||
await dictStore.getDictData();
|
||||
// 再初始化选项数据
|
||||
educationOptions.value = getTransformChildren('education', '学历要求').options || [];
|
||||
experienceOptions.value = getTransformChildren('experience', '工作经验').options || [];
|
||||
scaleOptions.value = getTransformChildren('scale', '公司规模').options || [];
|
||||
areaOptions.value = getTransformChildren('area', '地区').options || [];
|
||||
jobTypeOptions.value = getJobTypeData();
|
||||
} catch (error) {
|
||||
console.error('获取字典数据失败:', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
|
||||
// 处理选项选择
|
||||
@@ -195,7 +224,7 @@ const handleClose = () => {
|
||||
background-color: #fff;
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.filter-header {
|
||||
@@ -231,17 +260,17 @@ const handleClose = () => {
|
||||
}
|
||||
|
||||
.filter-tabs {
|
||||
width: 200rpx;
|
||||
border-right: 1rpx solid #eee;
|
||||
background-color: #f8f8f8;
|
||||
display: flex;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
flex-direction: column;
|
||||
|
||||
.tab-item {
|
||||
flex: 1;
|
||||
height: 90rpx;
|
||||
line-height: 90rpx;
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
position: relative;
|
||||
transition: all 0.3s ease;
|
||||
@@ -249,14 +278,15 @@ const handleClose = () => {
|
||||
&.active {
|
||||
color: #256BFA;
|
||||
font-weight: 600;
|
||||
background-color: #fff;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 25%;
|
||||
width: 50%;
|
||||
height: 4rpx;
|
||||
left: 0;
|
||||
top: 25%;
|
||||
width: 4rpx;
|
||||
height: 50%;
|
||||
background-color: #256BFA;
|
||||
border-radius: 2rpx;
|
||||
}
|
||||
@@ -268,6 +298,13 @@ const handleClose = () => {
|
||||
}
|
||||
}
|
||||
|
||||
.filter-right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.filter-content {
|
||||
flex: 1;
|
||||
padding: 40rpx 32rpx;
|
||||
|
||||
@@ -25,16 +25,20 @@
|
||||
<scroll-view scroll-y :show-scrollbar="false" class="chat-scroll">
|
||||
<view
|
||||
class="drawer-rows"
|
||||
@click="changeDialogue(item)"
|
||||
v-for="(item, index) in filteredList"
|
||||
:key="item.id"
|
||||
>
|
||||
<view
|
||||
v-if="!item.isTitle"
|
||||
class="drawer-row-list"
|
||||
:class="{ 'drawer-row-active': item.sessionId === chatSessionID }"
|
||||
>
|
||||
{{ item.title }}
|
||||
<view v-if="!item.isTitle" class="drawer-row-container">
|
||||
<view
|
||||
class="drawer-row-list"
|
||||
:class="{ 'drawer-row-active': item.sessionId === chatSessionID }"
|
||||
@click="changeDialogue(item)"
|
||||
>
|
||||
{{ item.title }}
|
||||
</view>
|
||||
<view class="drawer-row-delete" @click.stop="deleteDialogue(item)">
|
||||
<uni-icons type="trash" size="24" color="#FF4D4F"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<view class="drawer-row-title" v-else>
|
||||
{{ item.title }}
|
||||
@@ -166,6 +170,21 @@ const changeDialogue = (item) => {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const deleteDialogue = (item) => {
|
||||
if (item.sessionId) {
|
||||
uni.showModal({
|
||||
content: '确定删除该会话吗?',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
useChatGroupDBStore().deleteDialogue(item.sessionId);
|
||||
$api.msg('会话删除成功');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function updateSetting() {
|
||||
$api.msg('该功能正在开发中,敬请期待后续更新!');
|
||||
}
|
||||
@@ -271,33 +290,56 @@ footer-height = 98rpx
|
||||
flex: 1
|
||||
overflow: hidden
|
||||
.drawer-rows
|
||||
padding: 0 28rpx;
|
||||
// border-bottom: 2rpx dashed #e8e8e8
|
||||
overflow:hidden; //超出的文本隐藏
|
||||
text-overflow:ellipsis; //溢出用省略号显示
|
||||
white-space:nowrap; //溢出不换行
|
||||
.drawer-row-title
|
||||
color: #A6A6A6;
|
||||
font-weight: 500;
|
||||
font-weight: bold;
|
||||
font-size: 28rpx
|
||||
padding: 0 24rpx
|
||||
margin-top: 50rpx
|
||||
margin-bottom: 16rpx
|
||||
.drawer-row-list
|
||||
height: 66rpx;
|
||||
line-height: 66rpx
|
||||
font-size: 28rpx
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
font-weight: 500;
|
||||
color: #595959;
|
||||
padding: 0 24rpx
|
||||
.drawer-row-active
|
||||
.drawer-row-list:active
|
||||
color: #333333;
|
||||
background: #F6F6F6;
|
||||
border-radius: 16rpx 16rpx 16rpx 16rpx;
|
||||
padding: 0 28rpx;
|
||||
// border-bottom: 2rpx dashed #e8e8e8
|
||||
overflow:hidden; //超出的文本隐藏
|
||||
text-overflow:ellipsis; //溢出用省略号显示
|
||||
white-space:nowrap; //溢出不换行
|
||||
.drawer-row-title
|
||||
color: #A6A6A6;
|
||||
font-weight: 500;
|
||||
font-weight: bold;
|
||||
font-size: 28rpx
|
||||
padding: 0 24rpx
|
||||
margin-top: 50rpx
|
||||
margin-bottom: 16rpx
|
||||
.drawer-row-container
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: space-between
|
||||
padding: 0 24rpx
|
||||
height: 66rpx
|
||||
|
||||
.drawer-row-list
|
||||
flex: 1
|
||||
height: 66rpx
|
||||
line-height: 66rpx
|
||||
font-size: 28rpx
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
font-weight: 500;
|
||||
color: #595959;
|
||||
|
||||
.drawer-row-delete
|
||||
margin-left: 20rpx
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
padding: 10rpx
|
||||
opacity: 0.6
|
||||
&:hover
|
||||
&:active
|
||||
opacity: 1
|
||||
|
||||
.drawer-row-active
|
||||
color: #333333;
|
||||
background: #F6F6F6;
|
||||
border-radius: 16rpx 16rpx 16rpx 16rpx;
|
||||
|
||||
.drawer-row-list:active
|
||||
color: #333333;
|
||||
background: #F6F6F6;
|
||||
border-radius: 16rpx 16rpx 16rpx 16rpx;
|
||||
|
||||
|
||||
/* 主要内容区域 */
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
<template>
|
||||
<view class="chat-container">
|
||||
<!-- 选择模式操作栏 -->
|
||||
<view v-if="isSelectMode" class="select-mode-header">
|
||||
<view class="select-header-left">
|
||||
<view class="select-count">{{ selectedMessages.length }} 条已选择</view>
|
||||
<view class="select-all" @click="selectAllMessages">全选</view>
|
||||
</view>
|
||||
<view class="select-header-right">
|
||||
<view class="cancel-btn" @click="exitSelectMode">取消</view>
|
||||
<view class="delete-btn" @click="deleteSelectedMessages" :disabled="selectedMessages.length === 0">删除</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- Tab切换 -->
|
||||
<view class="tab-container">
|
||||
<view v-else class="tab-container">
|
||||
<view
|
||||
class="tab-item"
|
||||
:class="{ active: activeTab === 'policy' }"
|
||||
@@ -74,7 +85,15 @@
|
||||
:id="'msg-' + index"
|
||||
class="chat-item"
|
||||
:class="{ self: msg.self }"
|
||||
@longpress="handleLongPress(msg, index)"
|
||||
@click="isSelectMode ? toggleSelectMessage(index) : null"
|
||||
>
|
||||
<!-- 选择框 -->
|
||||
<view v-if="isSelectMode" class="message-checkbox">
|
||||
<view class="checkbox" :class="{ checked: selectedMessages.includes(index) }">
|
||||
<uni-icons v-if="selectedMessages.includes(index)" type="success" size="24" color="#FFFFFF"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<view class="message" v-if="msg.self">
|
||||
<view class="msg-filecontent" v-if="msg.files.length">
|
||||
<view
|
||||
@@ -96,7 +115,7 @@
|
||||
:content="msg.displayText"
|
||||
:typing="isTyping && messages.length - 1 === index"
|
||||
></md-render>
|
||||
<view class="message-controll" v-show="showControll(index)">
|
||||
<view class="message-controll" v-show="showControll(index) && !isSelectMode">
|
||||
<view class="controll-left">
|
||||
<image
|
||||
class="controll-icon btn-light"
|
||||
@@ -134,7 +153,7 @@
|
||||
<!-- guess -->
|
||||
<view
|
||||
class="guess"
|
||||
v-if="showGuess && !msg.self && messages.length - 1 === index && msg.displayText"
|
||||
v-if="showGuess && !msg.self && messages.length - 1 === index && msg.displayText && !isSelectMode"
|
||||
>
|
||||
<view class="gulist">
|
||||
<view
|
||||
@@ -198,7 +217,7 @@
|
||||
class="input"
|
||||
@confirm="sendMessage"
|
||||
:disabled="isTyping"
|
||||
:adjust-position="false"
|
||||
:adjust-position="true"
|
||||
placeholder="请输入您的职位名称、薪资要求、岗位地址"
|
||||
v-show="!isVoice"
|
||||
/>
|
||||
@@ -386,6 +405,9 @@ const cancelThreshold = 100;
|
||||
const speechIndex = ref(0);
|
||||
const isAudioPermission = ref(false);
|
||||
const feebackData = ref(null);
|
||||
// 删除功能相关状态
|
||||
const isSelectMode = ref(false);
|
||||
const selectedMessages = ref([]);
|
||||
// ref for DOM element
|
||||
const voiceBtn = ref(null);
|
||||
const feeback = ref(null);
|
||||
@@ -942,6 +964,88 @@ function shouldShowMessage(msg) {
|
||||
}
|
||||
}
|
||||
|
||||
// 长按事件处理函数
|
||||
function handleLongPress(msg, index) {
|
||||
isSelectMode.value = true;
|
||||
selectedMessages.value = [index];
|
||||
|
||||
// 如果长按的是用户消息,同时选中对应的AI回复
|
||||
if (msg.self) {
|
||||
const nextIndex = index + 1;
|
||||
if (nextIndex < messages.value.length && !messages.value[nextIndex].self) {
|
||||
selectedMessages.value.push(nextIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 选择/取消选择消息
|
||||
function toggleSelectMessage(index) {
|
||||
const msg = messages.value[index];
|
||||
const idx = selectedMessages.value.indexOf(index);
|
||||
|
||||
if (idx > -1) {
|
||||
// 取消选择
|
||||
selectedMessages.value.splice(idx, 1);
|
||||
|
||||
// 如果取消选择的是用户消息,同时取消选择对应的AI回复
|
||||
if (msg.self) {
|
||||
const nextIndex = index + 1;
|
||||
if (nextIndex < messages.value.length && !messages.value[nextIndex].self) {
|
||||
const aiIdx = selectedMessages.value.indexOf(nextIndex);
|
||||
if (aiIdx > -1) {
|
||||
selectedMessages.value.splice(aiIdx, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedMessages.value.length === 0) {
|
||||
isSelectMode.value = false;
|
||||
}
|
||||
} else {
|
||||
// 选择消息
|
||||
selectedMessages.value.push(index);
|
||||
|
||||
// 如果选择的是用户消息,同时选择对应的AI回复
|
||||
if (msg.self) {
|
||||
const nextIndex = index + 1;
|
||||
if (nextIndex < messages.value.length && !messages.value[nextIndex].self) {
|
||||
if (!selectedMessages.value.includes(nextIndex)) {
|
||||
selectedMessages.value.push(nextIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 退出选择模式
|
||||
function exitSelectMode() {
|
||||
isSelectMode.value = false;
|
||||
selectedMessages.value = [];
|
||||
}
|
||||
|
||||
// 全选消息
|
||||
function selectAllMessages() {
|
||||
selectedMessages.value = messages.value.map((_, index) => index);
|
||||
}
|
||||
|
||||
// 删除选中消息
|
||||
function deleteSelectedMessages() {
|
||||
if (selectedMessages.value.length === 0) return;
|
||||
|
||||
uni.showModal({
|
||||
content: `确定删除${selectedMessages.value.length}条消息吗?`,
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
// 调用store中的删除方法
|
||||
useChatGroupDBStore().deleteMessages(selectedMessages.value);
|
||||
// 退出选择模式
|
||||
exitSelectMode();
|
||||
$api.msg('消息删除成功');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
defineExpose({ scrollToBottom, closeGuess, closeFile, changeQueries, handleTouchCancel, switchTab });
|
||||
</script>
|
||||
|
||||
@@ -1473,4 +1577,88 @@ image-margin-top = 40rpx
|
||||
.tab-item:active {
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
/* 选择模式样式 */
|
||||
.select-mode-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 44rpx;
|
||||
height: 88rpx;
|
||||
background: #FFFFFF;
|
||||
border-bottom: 2rpx solid #F4F4F4;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.select-header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.select-count {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.select-all {
|
||||
font-size: 28rpx;
|
||||
color: #256BFA;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.select-header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 32rpx;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
font-size: 28rpx;
|
||||
color: #FF4444;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.delete-btn:disabled {
|
||||
color: #CCCCCC;
|
||||
}
|
||||
|
||||
/* 消息选择框样式 */
|
||||
.message-checkbox {
|
||||
margin-right: 12rpx;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding-top: 8rpx;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
border: 2rpx solid #CCCCCC;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.checkbox.checked {
|
||||
background-color: #256BFA;
|
||||
border-color: #256BFA;
|
||||
}
|
||||
|
||||
/* 调整消息项布局,为选择框留出空间 */
|
||||
.chat-item {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.chat-item .message {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
return {
|
||||
kw: "", //搜索关键
|
||||
user: uni.getStorageSync("CAuserInfo").user,
|
||||
winHeight: wx.getWindowInfo().windowHeight,
|
||||
jobDataList: [],
|
||||
jobList,
|
||||
scrollTop: 0, //tab标题的滚动条位置
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<text class="icon icon-101"></text>
|
||||
<text class="title">职业测评</text>
|
||||
</view>
|
||||
<view class="item" @click="navDetail(2)">
|
||||
<!-- <view class="item" @click="navDetail(2)">
|
||||
<text class="icon icon-102"></text>
|
||||
<text class="title">测评报告</text>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="head-title">探索中心</view>
|
||||
<view class="nav-block">
|
||||
@@ -68,8 +68,7 @@
|
||||
// 演示入
|
||||
navDetail(index){
|
||||
switch (index){
|
||||
case 1:
|
||||
case 2: {
|
||||
case 1: {
|
||||
uni.navigateTo({
|
||||
url: "/packageCa/pagesTest/testList"
|
||||
})
|
||||
|
||||
@@ -87,12 +87,13 @@
|
||||
<view class="cards" v-if="fairList.length">
|
||||
<view class="card press-button" v-for="(item, index) in fairList" :key="index"
|
||||
@click="goDetail(item.jobFairId)">
|
||||
<view class="center-date"
|
||||
:style="{ color: getTimeStatus(item.jobFairStartTime, item.jobFairEndTime).color,borderColor: getTimeStatus(item.jobFairStartTime, item.jobFairEndTime).color }">
|
||||
{{ getTimeStatus(item.jobFairStartTime, item.jobFairEndTime).statusText }}
|
||||
</view>
|
||||
<view class="card-title">
|
||||
{{ item.jobFairTitle }}
|
||||
<view class="center-date"
|
||||
:style="{ color: getTimeStatus(item.jobFairStartTime, item.jobFairEndTime).color,borderColor: getTimeStatus(item.jobFairStartTime, item.jobFairEndTime).color }">
|
||||
{{ getTimeStatus(item.jobFairStartTime, item.jobFairEndTime).statusText }}
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<view class="card-row">
|
||||
<text class="">{{ item.jobFairAddress }}</text>
|
||||
@@ -514,7 +515,6 @@
|
||||
} else {
|
||||
$api.msg('请先登录');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getFair(type = "add") {
|
||||
@@ -1012,10 +1012,21 @@
|
||||
|
||||
.cards .card {
|
||||
margin-top: 28rpx;
|
||||
padding: 32rpx;
|
||||
padding: 45rpx 32rpx 32rpx 32rpx;
|
||||
background: linear-gradient(to bottom, #e3efff 0%, #fbfdff 100%);
|
||||
box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0, 0, 0, 0.04);
|
||||
border-radius: 20rpx;
|
||||
position: relative;
|
||||
.center-date {
|
||||
font-weight: 400;
|
||||
font-size: 24rpx;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
border: 1rpx solid;
|
||||
padding: 5rpx 10rpx;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.cards .card-title {
|
||||
@@ -1041,16 +1052,7 @@
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.center-date {
|
||||
font-weight: 400;
|
||||
font-size: 24rpx;
|
||||
// position: absolute;
|
||||
// right: 0;
|
||||
// top: 0;
|
||||
border: 1rpx solid;
|
||||
padding: 5rpx 10rpx;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.cards .card-row {
|
||||
|
||||
@@ -50,7 +50,7 @@ const useDictStore = defineStore("dict", () => {
|
||||
return data
|
||||
})
|
||||
}
|
||||
const [education, experience, area, scale, sex, affiliation, nature, noticeType] =
|
||||
const [education, experience, area, scale, sex, affiliation, nature, noticeType] =
|
||||
await Promise.all([
|
||||
getDictSelectOption('education'),
|
||||
getDictSelectOption('experience'),
|
||||
@@ -74,6 +74,17 @@ const useDictStore = defineStore("dict", () => {
|
||||
getIndustryDict() // 获取行业
|
||||
} catch (error) {
|
||||
console.error('Error fetching dictionary data:', error);
|
||||
// 确保即使出错也能返回空数组
|
||||
if (!dictType && !dictName) {
|
||||
state.education = [];
|
||||
state.experience = [];
|
||||
state.area = [];
|
||||
state.scale = [];
|
||||
state.sex = [];
|
||||
state.affiliation = [];
|
||||
state.nature = [];
|
||||
state.noticeType = [];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -97,31 +108,31 @@ const useDictStore = defineStore("dict", () => {
|
||||
return null
|
||||
}
|
||||
|
||||
function dictLabel(dictType, value) {
|
||||
if (state[dictType] && Array.isArray(state[dictType])) {
|
||||
for (let i = 0; i < state[dictType].length; i++) {
|
||||
let element = state[dictType][i];
|
||||
if (element.value === value) {
|
||||
return element.label
|
||||
}
|
||||
}
|
||||
}
|
||||
return ''
|
||||
function dictLabel(dictType, value) {
|
||||
if (state[dictType] && Array.isArray(state[dictType])) {
|
||||
for (let i = 0; i < state[dictType].length; i++) {
|
||||
let element = state[dictType][i];
|
||||
if (element.value === value) {
|
||||
return element.label
|
||||
}
|
||||
}
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function oneDictData(dictType, value) {
|
||||
if (!value) {
|
||||
return state[dictType]
|
||||
}
|
||||
if (state[dictType]) {
|
||||
for (let i = 0; i < state[dictType].length; i++) {
|
||||
let element = state[dictType][i];
|
||||
if (element.value === value) {
|
||||
return element
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
function oneDictData(dictType, value) {
|
||||
if (!value) {
|
||||
return state[dictType]
|
||||
}
|
||||
if (state[dictType]) {
|
||||
for (let i = 0; i < state[dictType].length; i++) {
|
||||
let element = state[dictType][i];
|
||||
if (element.value === value) {
|
||||
return element
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function getTransformChildren(dictType, title = '', key = '') {
|
||||
@@ -129,7 +140,7 @@ const useDictStore = defineStore("dict", () => {
|
||||
return {
|
||||
label: title,
|
||||
key: key || dictType,
|
||||
options: state[dictType],
|
||||
options: state[dictType] || [],
|
||||
}
|
||||
}
|
||||
return null
|
||||
|
||||
@@ -335,6 +335,72 @@ const useChatGroupDBStore = defineStore("messageGroup", () => {
|
||||
}))
|
||||
}
|
||||
|
||||
// 删除消息
|
||||
async function deleteMessages(indices) {
|
||||
// 按索引从大到小排序,避免删除时索引变化
|
||||
const sortedIndices = [...indices].sort((a, b) => b - a);
|
||||
|
||||
// 从内存中删除消息
|
||||
for (const index of sortedIndices) {
|
||||
const message = messages.value[index];
|
||||
if (message && message.id) {
|
||||
// 从本地数据库中删除
|
||||
await baseDB.db.delete(massageName.value, message.id);
|
||||
}
|
||||
messages.value.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除会话
|
||||
async function deleteDialogue(sessionId) {
|
||||
if (!baseDB.isDBReady) await baseDB.initDB();
|
||||
|
||||
// 删除会话下的所有消息
|
||||
const messageList = await baseDB.db.queryByField(massageName.value, 'parentGroupId', sessionId);
|
||||
for (const message of messageList) {
|
||||
if (message.id) {
|
||||
await baseDB.db.delete(massageName.value, message.id);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除会话本身
|
||||
const sessionList = await baseDB.db.queryByField(tableName.value, 'sessionId', sessionId);
|
||||
for (const session of sessionList) {
|
||||
if (session.id) {
|
||||
await baseDB.db.delete(tableName.value, session.id);
|
||||
}
|
||||
}
|
||||
|
||||
// 重新获取所有会话并重新分组
|
||||
const allSessions = await baseDB.db.getAll(tableName.value);
|
||||
if (allSessions.length) {
|
||||
const [result, lastData] = insertSortData(allSessions);
|
||||
tabeList.value = result;
|
||||
} else {
|
||||
tabeList.value = [];
|
||||
}
|
||||
|
||||
// 如果删除的是当前会话,切换到第一个会话或清空
|
||||
if (chatSessionID.value === sessionId) {
|
||||
if (tabeList.value.length > 0) {
|
||||
// 找到第一个非标题的会话
|
||||
const firstSession = tabeList.value.find(item => !item.isTitle);
|
||||
if (firstSession) {
|
||||
chatSessionID.value = firstSession.sessionId;
|
||||
await initMessage(firstSession.sessionId);
|
||||
} else {
|
||||
// 没有会话了
|
||||
chatSessionID.value = '';
|
||||
messages.value = [];
|
||||
}
|
||||
} else {
|
||||
// 没有会话了
|
||||
chatSessionID.value = '';
|
||||
messages.value = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
messages,
|
||||
isTyping,
|
||||
@@ -348,7 +414,9 @@ const useChatGroupDBStore = defineStore("messageGroup", () => {
|
||||
changeDialogue,
|
||||
getStearm,
|
||||
getHistory,
|
||||
badFeedback
|
||||
badFeedback,
|
||||
deleteMessages,
|
||||
deleteDialogue
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user