| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- <template>
- <view class="box">
- <u-navbar
- @leftClick="rightClick"
- title="志愿者招募"
- bgColor="rgba(255,255,255,0)"
- :placeholder="true"
- titleStyle="font-weight:bold;color:#000000"
- ></u-navbar>
- <view class="fj_box">
- <view class="scarch_box2">
- <u--input
- @change="search"
- @input="onInputChange"
- placeholderStyle="color: #985741"
- height="25"
- prefixIcon="search"
- shape="square"
- placeholder="输入文物关键词"
- v-model.trim="value"
- ></u--input>
- </view>
- </view>
- <view style="position: relative">
- <u-transition :show="searchList.length > 0">
- <scroll-view v-if="searchList.length > 0" class="search_box" scroll-y="true" @scrolltolower="LoadMore">
- <view>
- <view @click="searchItem(item)" class="item_tit" v-for="item in searchList" :key="item.id">
- {{ item.title }}
- </view>
- </view>
- </scroll-view>
- </u-transition>
- </view>
- <u-popup :show="introduceShow" @close="close" mode="center" :closeable="true" bgColor="#f9dbbf" round="5">
- <view class="xx_box">
- <view style="font-size: 40rpx; font-weight: bold; text-align: center;">{{ claimDetails.title }}</view>
- <view class="xx_tit" v-if="claimDetails.intro">
- <u-parse :content="claimDetails.intro"></u-parse>
- </view>
- <view v-else>
- <u-empty text="该文物暂无介绍" iconColor="#4a433d" textColor="#4a433d" mode="data"></u-empty>
- </view>
- <view style="font-size: 28rpx; color: #666666; padding-top: 10rpx;">{{ claimDetails.address }}</view>
- <view class="claim_tit" @click="claimBtn">巡查志愿者报名</view>
- </view>
- </u-popup>
- <view>
- <mapComponent
- ref="mychild"
- @subComponent="subComponent"
- :markers="markers"
- :height="height"
- :latitudeAndLongitude="latitudeAndLongitude"
- :introduceShow="introduceShow"
- ></mapComponent>
- </view>
- </view>
- </template>
- <script>
- const ROLE_FIELD_CONFIG = [
- {
- key: 'patrol',
- label: '文物巡查',
- fields: ['patrolCount', 'patrol_count', 'wenwu_patrol_count', 'xuncha_count', 'inspection_count']
- },
- {
- key: 'lecture',
- label: '宣讲',
- fields: ['lectureCount', 'lecture_count', 'xuanjiang_count', 'preach_count']
- },
- {
- key: 'spread',
- label: '传播',
- fields: ['spreadCount', 'spread_count', 'communication_count', 'propagation_count']
- }
- ];
- // 现在接口里还没有岗位数量,这里先放一组稳定的假数据,方便联调视觉效果。
- const ENABLE_MOCK_ROLE_COUNT = true;
- const MOCK_ROLE_COUNTS = {
- patrol: 2,
- lecture: 1,
- spread: 3
- };
- export default {
- data() {
- return {
- volunteer_id: '',
- longitude: '',
- latitude: '',
- page: 1,
- searchList: [],
- isProcessingItemClick: false,
- preventSearchOnChange: false,
- prevSearchVal: '',
- value: '',
- height: '1360',
- latitudeAndLongitude: {
- latitude: '24.504403',
- longitude: '118.143033',
- anchorPoint: true
- },
- markers: [],
- claimDetails: {},
- introduceShow: false,
- entryOptions: {}
- };
- },
- onLoad(options) {
- // 扫码进入时,scene 会带在页面参数中,这里统一解析成普通对象。
- this.entryOptions = this.parseEntryOptions(options);
- this.applyEntryOptions(this.entryOptions);
- this.details();
- // Temporary: use getScanContentList for scan signup page until the dedicated API is ready.
- this.getScanContentList();
- },
- methods: {
- parseEntryOptions(options = {}) {
- const parsedOptions = { ...options };
- if (options.scene) {
- const decodedScene = decodeURIComponent(options.scene);
- decodedScene.split('&').forEach((segment) => {
- if (!segment) {
- return;
- }
- const [rawKey, rawValue = ''] = segment.split('=');
- if (!rawKey) {
- return;
- }
- parsedOptions[rawKey] = decodeURIComponent(rawValue);
- });
- }
- return parsedOptions;
- },
- // 把二维码参数里的定位或关键词直接带入首屏,方便后面按点位跳转。
- applyEntryOptions(options = {}) {
- const keyword = options.keywords || options.keyword || options.title || '';
- if (keyword) {
- this.value = keyword;
- this.prevSearchVal = keyword;
- }
- if (options.latitude && options.longitude) {
- this.latitude = options.latitude;
- this.longitude = options.longitude;
- this.latitudeAndLongitude.latitude = options.latitude;
- this.latitudeAndLongitude.longitude = options.longitude;
- }
- },
- search() {
- if (this.preventSearchOnChange) {
- this.preventSearchOnChange = false;
- return;
- }
- if (this.value) {
- if (this.prevSearchVal !== this.value) {
- this.prevSearchVal = this.value;
- this.page = 1;
- this.searchList = [];
- }
- // Temporary: search suggestions still use getScanContentList and will switch to the new scan API later.
- this.$api.getScanContentList(
- {
- main_body_id: 1,
- model_id: 1,
- keywords: this.value || '',
- page: this.page,
- claim_status: '0',
- pageSize: '10'
- },
- (res) => {
- const list = Array.isArray(res.data) ? res.data : [];
- this.searchList = this.page === 1 ? list : [...this.searchList, ...list];
- }
- );
- } else {
- this.searchList = [];
- this.page = 1;
- this.prevSearchVal = '';
- this.getScanContentList();
- }
- },
- onInputChange(value) {
- if (!this.isProcessingItemClick) {
- this.value = value;
- }
- },
- searchItem(item) {
- this.isProcessingItemClick = true;
- this.page = 1;
- this.value = item.title;
- this.prevSearchVal = item.title;
- this.searchList = [];
- this.$nextTick(() => {
- this.isProcessingItemClick = false;
- });
- this.latitude = item.latitude || '';
- this.longitude = item.longitude || '';
- this.latitudeAndLongitude.latitude = item.latitude || this.latitudeAndLongitude.latitude;
- this.latitudeAndLongitude.longitude = item.longitude || this.latitudeAndLongitude.longitude;
- this.getScanContentList();
- },
- LoadMore() {
- if (!this.value) {
- return;
- }
- this.page++;
- this.search();
- },
- getScanContentList() {
- // Temporary: use getScanContentList for scan signup page until the dedicated API is ready.
- this.$api.getScanContentList(
- {
- model_id: '1',
- main_body_id: '1',
- page: 1,
- pageSize: '100',
- region: 5,
- keywords: this.value,
- longitude: this.longitude,
- latitude: this.latitude
- },
- (res) => {
- const list = Array.isArray(res.data) ? res.data : [];
- if (this.value && list.length <= 0) {
- this.$common.errorToShow('该文物已被认领');
- }
- this.markers = list.map((item) => this.buildMarker(item));
- }
- );
- },
- // 统一构造 marker,后续换新接口时只需要改这里的字段映射即可。
- buildMarker(item) {
- return {
- id: parseFloat(item.id),
- latitude: parseFloat(item.latitude),
- longitude: parseFloat(item.longitude),
- iconPath: '/static/img/icon_map.png',
- width: 1,
- height: 1,
- alpha: 0,
- title: item.title,
- customCallout: {
- display: 'ALWAYS'
- },
- joinCluster: true,
- };
- },
- getRoleCount(source, fields = []) {
- for (let index = 0; index < fields.length; index++) {
- const field = fields[index];
- if (source[field] !== undefined && source[field] !== null && source[field] !== '') {
- const count = Number(source[field]);
- if (!Number.isNaN(count) && count > 0) {
- return count;
- }
- }
- }
- return 0;
- },
- // 点击 marker 后先用列表数据秒开岗位标签,再异步拉详情补全图文信息。
- subComponent(newShow, id) {
- this.introduceShow = newShow;
- this.claimDetails = {};
- this.$api.getContentDetail(
- {
- main_body_id: 1,
- id: id
- },
- (res) => {
- this.claimDetails = res.data || {};
- }
- );
- },
- details() {
- this.$api.details({ main_body_id: 1 }, (res) => {
- if (res.code == 1) {
- this.volunteer_id = res.data.id;
- }
- });
- },
- claimBtn() {
- if (this.claimDetails.claim_status === 1 && this.claimDetails.is_multiple_claims === 0) {
- this.$common.errorToShow('该文物已被认领');
- } else if (this.volunteer_id !== undefined && this.volunteer_id !== '') {
- this.$api.claimCr(
- {
- main_body_id: 1,
- type: 'volunteer',
- volunteer_id: this.volunteer_id,
- cr_id: this.claimDetails.id,
- cr_code: this.claimDetails.code,
- desc: ''
- },
- (res) => {
- this.$common.errorToShow(res.msg);
- }
- );
- } else {
- uni.navigateTo({
- url: '/index_fenbao/fuWu/baoMing/baoMing2?type=volunteer&id=' + this.claimDetails.id
- });
- }
- },
- rightClick() {
- uni.navigateBack({
- fail() {
- uni.switchTab({
- url: '/pages/index/index'
- });
- }
- });
- },
- close() {
- this.introduceShow = false;
- // 这里不能立刻清空弹窗内容。
- // u-popup 的 close 事件发生在收起动画开始时,如果马上把详情数据清掉,
- // 用户就会看到同一个弹窗在收起过程中闪成“暂无图片/暂无介绍”的空弹窗。
- }
- }
- };
- </script>
- <style>
- ::v-deep .u-swiper-indicator__wrapper__dot--active {
- width: 5px !important;
- }
- .box {
- height: 100%;
- width: 100%;
- padding-bottom: 50rpx;
- background-image: url('https://huli-app.wenlvti.net/app_static/WenWuGuanJia/image/xy_bgt.png');
- background-repeat: repeat-y;
- background-size: cover;
- background-size: 100% 100%;
- }
- .fj_box {
- width: 90%;
- margin: auto;
- margin-top: 40rpx;
- margin-bottom: 20rpx;
- }
- .scarch_box2 {
- width: 674rpx;
- height: 82rpx;
- padding: 6rpx 0 0 30rpx;
- margin-top: 20rpx;
- background-image: url('/static/img/search_bg1.png');
- background-size: 100% 100%;
- }
- .xx_box {
- padding: 20rpx;
- background-color: #e1bf9a;
- width: 660rpx;
- padding-top: 80rpx;
- }
- .xx_tit {
- height: 360rpx;
- font-size: 30rpx;
- padding: 20rpx;
- text-indent: 2em;
- margin-top: 30rpx;
- background-color: #f3e3d3;
- overflow: scroll;
- }
- .role_box {
- display: flex;
- flex-wrap: wrap;
- gap: 18rpx;
- margin-top: 24rpx;
- }
- .role_item {
- padding: 12rpx 24rpx;
- border-radius: 999rpx;
- background: #f7e3d0;
- color: #6a412c;
- font-size: 28rpx;
- line-height: 1;
- border: 2rpx solid rgba(202, 86, 66, 0.2);
- }
- .role_count {
- color: #ca5642;
- font-weight: 700;
- }
- .claim_tit {
- /* width: 190rpx; */
- padding: 8rpx 20rpx;
- height: 70rpx;
- margin: 30rpx auto 0;
- font-weight: 600;
- text-align: center;
- line-height: 70rpx;
- font-size: 32rpx;
- background-color: #efb681;
- }
- .search_box {
- width: 87%;
- position: absolute;
- height: 400rpx;
- z-index: 9;
- left: 50rpx;
- padding: 40rpx;
- background-color: #f7dfc0;
- }
- .item_tit {
- line-height: 50rpx;
- font-size: 30rpx;
- }
- </style>
|