123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592 |
- <template>
- <view class="publishMain" :style="{ paddingTop: barHeight + 'px' }">
- <!-- <uni-popup ref="addressPopup" background-color="#fff">
- <view class="popup-content">
- <LocalSearch
- @changeAddress="changeAddress"
- @closeSelectAddress="closeSelectAddress"
- ref="localRef"
- ></LocalSearch>
- </view>
- </uni-popup> -->
- <page-container :show='pageContainerShow' :overlay="pageContainerOverlay" position='right' @beforeleave='afterenter' ref="addressPopup" background-color="#fff">
- <view class="popup-content">
- <LocalSearch
- @changeAddress="changeAddress"
- @closeSelectAddress="closeSelectAddress"
- ref="localRef"
- ></LocalSearch>
- </view>
- </page-container>
- <view class="content">
- <uni-easyinput type="textarea" v-model="formDatas.title" placeholder="来点内容吧..." />
- <view class="fileBox">
- <view class="fileItem" v-for="(item, index) in fileList" :key="index">
- <image
- src="../../static/image/delete.png"
- @click="deleteFiles(index)"
- class="deleteFile"
- ></image>
- <image
- :src="item.materialUrl"
- class="thumbnail"
- v-if="item.fileType === 'image'"
- @click="previewFile(index)"
- mode="aspectFill"
- ></image>
- <view
- class="defaultFileItem"
- v-else-if="item.fileType === 'video'"
- @click="previewFile(index)"
- >
- <image src="../../static/image/video.png" class="thumbnail"></image>
- <image src="../../static/image/playBtn.png" class="playBtn"></image>
- </view>
- <view class="defaultFileItem" v-else @click="previewFile(index)">
- <image src="../../static/image/music.png" class="thumbnail"></image>
- <image src="../../static/image/playBtn.png" class="playBtn"></image>
- </view>
- </view>
- <view class="fileItem addFileBtn" v-if="fileList.length < 9" @click="addFile"></view>
- </view>
- <view class="formBox">
- <view class="phoneBox">
- <view class="label">
- 手机号
- </view>
- <view class="textRight">
- {{ phone }}
- </view>
- </view>
- <uni-forms id="publishForm" ref="valiForm" :rules="rules" :modelValue="formDatas">
- <uni-forms-item label="地点" required name="tipAddress">
- <view class="selectInputBox" @click="openSelectAddress">
- <text :class="formDatas.tipAddress == '' ? 'addressNoText' : ''">
- {{ formatAddress(formDatas.tipAddress) || '请选择' }}
- </text>
- <text class="rightIcon">{{ '>' }}</text>
- </view>
- </uni-forms-item>
- <uni-forms-item label="昵称" required name="tipUsername">
- <uni-easyinput type="nickname" v-model="formDatas.tipUsername" placeholder="请输入" class="textRight" />
- </uni-forms-item>
- <!-- <uni-forms-item label="发布部门" required name="ascriptionName">
- <view class="selectInputBox" @click="openAscriptionAction">
- <text>{{ formDatas.ascriptionName }}</text>
- <text class="rightIcon">{{ '>' }}</text>
- </view>
- </uni-forms-item> -->
- </uni-forms>
- </view>
- </view>
- <view class="publishBtn" @click="publishNews()">发布</view>
- <view class="popupBottom" v-if="isshowAudio" @touchmove.stop.prevent="moveStop">
- <view class="popupBg" @click="isshowAudio = false"></view>
- <view class="popupContent">
- <sound-recording
- :maximum="15"
- :duration="100"
- @cancel="isshowAudio = false"
- @confirm="uploadFile"
- ></sound-recording>
- </view>
- </view>
- <view class="popupBottom" v-if="previewModal" @touchmove.stop.prevent="moveStop">
- <view class="popupSwiperBg" @click="previewModal = false"></view>
- <view class="swiperDotBox">
- <swiper class="swiperBox" @change="swiperChange" :current="previewIndex - 1">
- <swiper-item v-for="(item, index) in fileList" :key="index">
- <image
- :src="item.materialUrl"
- class="swiperFileItem"
- v-if="item.fileType === 'image'"
- mode="aspectFit"
- @click="previewModal = false"
- ></image>
- <video
- :src="item.materialUrl"
- class="swiperFileItem"
- :show-fullscreen-btn="false"
- controls
- ></video>
- <video
- </swiper-item>
- </swiper>
- <view class="swiperPage">{{ `${previewIndex} / ${fileList.length}` }}</view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import { saveClue, uploadMediaFile } from '../../network/api.js';
- import { LocalSearch } from '../../components/localSearch/localSearch.vue';
- import { mapState, mapMutations } from 'vuex';
- export default {
- components: {
- LocalSearch
- },
- computed: {
- ...mapState(['userInfo'])
- },
- data() {
- return {
- phone: '',
- previewIndex: 0,
- previewModal: false,
- isSubmitForm: true,
- isshowAudio: false,
- fileList: [],
- formDatas: {
- title: '', //标题
- tipAddress: '', //地址
- tipUsername: '', //昵称
- // ascription: 1,
- // ascriptionName: '都市快报'
- },
- barHeight: uni.getSystemInfoSync().statusBarHeight,
- rules: {
- tipAddress: {
- rules: [
- {
- required: true,
- errorMessage: '请选择地点'
- }
- ]
- },
- tipUsername: {
- rules: [
- {
- required: true,
- errorMessage: '昵称不能为空'
- }
- ]
- }
- },
- pageContainerShow:false,
- pageContainerOverlay:false
- };
- },
- mounted() {
- this.phone = this.userInfo.phone
- this.formDatas.tipUsername = this.userInfo.name
- this.$refs.valiForm.setValue('tipUsername', this.userInfo.name)
- },
- methods: {
- ...mapMutations(['setUserInfo']),
- deleteFiles(index) {
- this.fileList.splice(index, 1);
- },
- swiperChange(e) {
- this.previewIndex = e.detail.current + 1;
- },
- previewFile(index) {
- this.previewIndex = index + 1;
- this.previewModal = true;
- },
- moveStop() {},
- openAscriptionAction() {
- let action = ['都市快报', '第一新闻热线', '管理中心'];
- uni.showActionSheet({
- itemList: action,
- success: res => {
- this.formDatas.ascription = res.tapIndex + 1;
- this.formDatas.ascriptionName = action[res.tapIndex];
- }
- });
- },
- addFile() {
- let action = ['图片', '视频', '音频'];
- uni.showActionSheet({
- itemList: action,
- success: res => {
- let actionMethods = ['photo', 'video', 'audio'];
- this[actionMethods[res.tapIndex]]();
- }
- });
- },
- photo() {
- uni.chooseImage({
- success: res => {
- console.log(res);
- this.uploadFiles(res.tempFilePaths, 'image');
- }
- });
- },
- video() {
- uni.chooseMedia({
- count: 9,
- mediaType: ['image', 'video'],
- maxDuration: 60,
- camera: 'back',
- success: res => {
- console.log(res);
- this.uploadFiles(res.tempFiles, 'video');
- }
- });
- },
- videoCompress(tempFilePath) {
- return new Promise((resolve, reject) => {
- uni.compressVideo({
- src: tempFilePath,
- quality: 'medium', //'low':低,'medium':中,'high':高
- success: res => {
- console.log('压缩后', res);
- resolve(res.tempFilePath);
- },
- fail: err => {
- reject(err);
- }
- });
- });
- },
- async uploadFiles(file, type) {
- console.log(file);
- for (let i = 0; i < file.length; i++) {
- if (this.fileList.length >= 9) {
- uni.showToast({
- title: '已上传九个素材,无法再上传!',
- duration: 1000,
- icon: 'none'
- });
- break;
- }
- let path = file[i];
- if (type == 'video') {
- path = await this.videoCompress(path.tempFilePath).catch(err => {
- console.log(err);
- uni.showToast({
- title: err,
- duration: 1000
- });
- });
- }
- if (!path) continue;
- let mediaType = {
- image: {
- type: 1,
- fileType: 'image'
- },
- video: {
- type: 2,
- fileType: 'video'
- },
- audio: {
- type: 3,
- fileType: 'voice'
- },
- };
- let params = {
- filePath: path,
- formData: {
- mediaType: mediaType[type].fileType
- },
- fileType: type
- };
- let result = await uploadMediaFile(params);
- if (result.state === 200) {
- this.fileList.push({
- materialUrl: result.data,
- fileType: type,
- type: mediaType[type].type
- });
- } else {
- uni.showToast({
- title: '上传失败!',
- duration: 1000,
- icon: 'error'
- });
- }
- }
- },
- audio() {
- this.isshowAudio = true;
- },
- uploadFile(tempFilePath) {
- this.uploadFiles([tempFilePath], 'audio');
- this.isshowAudio = false;
- },
- afterenter(){
- this.pageContainerShow = false
- this.pageContainerOverlay = false
- },
- openSelectAddress() {
- // this.$refs.addressPopup.open('bottom');
- this.pageContainerShow = true
- this.pageContainerOverlay = true
- },
- closeSelectAddress() {
- // this.$refs.addressPopup.close();
- this.pageContainerShow = false
- this.pageContainerOverlay = false
- },
- changeAddress(text) {
- this.formDatas.tipAddress = text;
- this.$refs.valiForm.setValue('tipAddress', text);
- this.closeSelectAddress();
- },
- back() {
- uni.navigateBack();
- },
- publishNews() {
- if (!this.isSubmitForm) return;
- this.$refs.valiForm
- .validate(async (err, formData) => {
- if (!err) {
- console.log('success', formData);
- this.formDatas.title = this.formDatas.title.trim();
- if (this.formDatas.title.length === 0) {
- uni.showToast({
- title: '内容不能为空',
- duration: 2000,
- icon: 'none'
- });
- return;
- }
- this.isSubmitForm = false;
- let params = {
- ascription: 1,
- source: 4,
- title: this.formDatas.title,
- phone: this.userInfo.phone,
- address: formData.tipAddress,
- author: formData.tipUsername,
- clueInfoList: this.fileList
- };
- let res = await saveClue(params);
- if (res.data.state === 200) {
- uni.showToast({
- duration: 2000,
- title: '发布成功!',
- icon: 'success'
- });
-
- let userInfos = Object.assign({}, this.userInfo)
- userInfos.name = formData.tipUsername
- this.setUserInfo(userInfos)
- uni.setStorageSync('userInfo', JSON.stringify(userInfos))
-
- this.formDatas = this.$options.data().formDatas;
- this.fileList = [];
- this.$refs.localRef.initIndex()
- this.$refs.valiForm.resetFields();
- this.formDatas.tipUsername = this.userInfo.name
- this.$refs.valiForm.setValue('tipUsername', this.userInfo.name)
- } else {
- uni.showToast({
- duration: 2000,
- title: res.data.message,
- icon: 'none'
- });
- }
- this.isSubmitForm = true;
- }
- })
- .then(res => {
- // res 返回 null
- uni.showToast({
- title: res,
- icon: 'none'
- })
- });
- },
- formatAddress(item) {
- return item.length > 8 ? item.substring(0, 7) + '...' : item;
- }
- }
- };
- </script>
- <style lang="scss" scoped>
- .publishMain {
- box-sizing: border-box;
- padding: 0 32rpx 32rpx 32rpx;
- width: 100%;
- .header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- height: 49px;
- }
- .content {
- .fileBox {
- display: flex;
- flex-wrap: wrap;
- margin-top: 10px;
- .fileItem {
- width: 218rpx;
- height: 218rpx;
- background-color: #a5a5a5;
- position: relative;
- margin-right: 16rpx;
- &:nth-child(3n) {
- margin-right: 0;
- }
- &:nth-child(n + 4) {
- margin-top: 16rpx;
- }
- .thumbnail {
- width: 100%;
- height: 100%;
- }
- .defaultFileItem {
- position: relative;
- width: 100%;
- height: 100%;
- .playBtn {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 48rpx;
- height: 48rpx;
- }
- }
- .deleteFile {
- width: 20px;
- height: 20px;
- position: absolute;
- top: 0;
- right: 0;
- z-index: 10;
- }
- }
- .addFileBtn {
- background-image: url(../../static/image/addFile.png);
- background-position: center center;
- background-repeat: no-repeat;
- background-color: #ffffff;
- background-size: 100%;
- }
- }
- .formBox {
- margin-top: 56rpx;
- .phoneBox{
- display: flex;
- padding-bottom: 22px;
- justify-content: space-between;
- .label{
- font-size: 13px;
- color: #666666;
- padding-left: 5px;
- position: relative;
- &::before{
- content: '*';
- position: absolute;
- left: -1px;
- top: 0;
- color: red;
- }
- }
- }
- .textRight {
- /deep/.is-input-border {
- border: none;
- text-align: right;
- }
- /deep/.is-disabled {
- background-color: #ffffff !important;
- }
- }
- .selectInputBox {
- height: 100%;
- display: flex;
- justify-content: flex-end;
- align-items: center;
- .rightIcon {
- margin-left: 16rpx;
- }
- .addressNoText {
- color: #d5d5d5;
- }
- }
- }
- }
- .popup-content {
- height: 100vh;
- }
- .publishBtn {
- width: 686rpx;
- height: 44px;
- line-height: 44px;
- text-align: center;
- margin: 15px auto 0 auto;
- background-color: #007aff;
- border-radius: 8px;
- color: #ffffff;
- }
- .popupBottom {
- position: fixed;
- bottom: 0;
- left: 0;
- width: 100%;
- height: 100%;
- z-index: 100;
- display: flex;
- flex-direction: column;
- .popupBg {
- position: fixed;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- background: rgba(0, 0, 0, 0.5);
- }
- .popupContent {
- height: 40%;
- margin-top: auto;
- background-color: #fff;
- position: relative;
- z-index: 11;
- }
- .popupSwiperBg {
- position: fixed;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- background: rgba(0, 0, 0, 0.5);
- display: flex;
- align-items: center;
- }
- .swiperDotBox {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100%;
- width: 100%;
- flex-direction: column;
- .swiperBox {
- height: 85vh;
- width: 100%;
- }
- .swiperFileItem {
- width: 100%;
- height: 100%;
- }
- .swiperAudioBox {
- width: 100%;
- height: 100%;
- position: relative;
- }
- .swiperAudioItem {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- z-index: 111;
- }
- .swiperPage {
- position: absolute;
- bottom: 20rpx;
- width: 100%;
- height: 30px;
- text-align: center;
- line-height: 30px;
- color: #ffffff;
- }
- }
- }
- }
- </style>
|