瑶都万能墙
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

475 lines
9.8 KiB

11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
10 months ago
11 months ago
10 months ago
10 months ago
11 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
  1. <template>
  2. <view class="publishPost">
  3. <navbar
  4. leftClick
  5. @leftClick="$utils.navigateBack"
  6. title="发布动态"/>
  7. <!-- <view class="title-input box">
  8. <input type="text" placeholder="取个吸引人的标题吧" v-model="form.title"/>
  9. </view> -->
  10. <view class="content-input">
  11. <uv-textarea
  12. v-model="form.title"
  13. :maxlength="200"
  14. autoHeight
  15. count
  16. style="min-height: 400rpx;"
  17. placeholder="说点什么吧"></uv-textarea>
  18. </view>
  19. <view class="images box">
  20. <uv-upload
  21. :fileList="fileList"
  22. :maxCount="imageMax"
  23. multiple
  24. width="150rpx"
  25. height="150rpx"
  26. name="fileList"
  27. @delete="deleteImage"
  28. @afterRead="afterRead"
  29. :previewFullImage="true"
  30. :accept="'image,video'"
  31. :sizeType="['original', 'compressed']"
  32. :sourceType="['album', 'camera']"></uv-upload>
  33. </view>
  34. <view class="category">
  35. <view class="title">
  36. 选择分类
  37. </view>
  38. <view class="tagList">
  39. <view
  40. :class="{act : t.id == form.classId}"
  41. @click="clickCategory(t, i)"
  42. v-for="(t, i) in category"
  43. :key="i">
  44. {{ t.title }}
  45. </view>
  46. </view>
  47. </view>
  48. <!-- <view class="category">
  49. <view class="title">
  50. 选择地区
  51. </view>
  52. <view class="tagList">
  53. <view
  54. :class="{act : t.name == form.address}"
  55. @click="clickAddress(t, i)"
  56. v-for="(t, i) in cityList"
  57. :key="i">
  58. {{ t.name }}
  59. </view>
  60. </view>
  61. </view> -->
  62. <view class="category"
  63. v-if="categoryRole.includes('code')">
  64. <view class="title">
  65. 上传微信二维码必填
  66. </view>
  67. <view class="images box">
  68. <uv-upload
  69. :fileList="codeFileList"
  70. :maxCount="1"
  71. multiple
  72. width="150rpx"
  73. height="150rpx"
  74. name="codeFileList"
  75. @delete="deleteImage"
  76. @afterRead="afterRead"
  77. :previewFullImage="true"></uv-upload>
  78. </view>
  79. </view>
  80. <view class="title-input box"
  81. v-if="categoryRole.includes('phone')">
  82. <input type="text" placeholder="手机号码(选填)" v-model="form.phone"/>
  83. </view>
  84. <view class="title-input box"
  85. v-if="categoryRole.includes('address')"
  86. @click="selectAddr">
  87. <input type="text"
  88. placeholder="选择位置(选填)"
  89. disabled
  90. v-model="form.address"/>
  91. <uv-icon
  92. size="40rpx"
  93. name="map"></uv-icon>
  94. </view>
  95. <view class="title-input box"
  96. @click="$refs.pickerHospital.open()"
  97. v-if="categoryRole.includes('shop')">
  98. <input type="text"
  99. v-if="!form.shop"
  100. placeholder="关联店铺(选填)"/>
  101. <view class="shop-box"
  102. v-else>
  103. <view class="title">
  104. {{ form.shop.title }}
  105. </view>
  106. <view class="desc">
  107. {{ form.shop.address }}
  108. </view>
  109. </view>
  110. </view>
  111. <view class="configBtn"
  112. @click="$refs.configPopup.open()">
  113. 发布须知
  114. </view>
  115. <view class="uni-color-btn"
  116. @click="submit">
  117. 发布
  118. </view>
  119. <configPopup
  120. ref="configPopup"
  121. :text="headInfo.save_no && headInfo.save_no.keyDetails"
  122. />
  123. <pickerHospital
  124. mixinsListApi="getStorePage"
  125. descKeyName="address"
  126. keyName="title"
  127. searchKey="title"
  128. ref="pickerHospital"
  129. @select="selectShop"
  130. />
  131. </view>
  132. </template>
  133. <script>
  134. import { mapState } from 'vuex'
  135. import Position from '@/utils/position.js'
  136. import pickerHospital from '@/components/base/pickerHospital.vue'
  137. export default {
  138. components : {
  139. pickerHospital,
  140. },
  141. data() {
  142. return {
  143. form : {
  144. title : '',
  145. classId : 0,
  146. address : '',
  147. phone : '',
  148. shop : '',
  149. },
  150. id : 0,
  151. fileList : [],
  152. codeFileList : [],
  153. imageMax : 9,
  154. };
  155. },
  156. computed : {
  157. ...mapState(['cityList', 'category', 'headInfo']),
  158. categoryRole(){
  159. if(!this.form.classId){
  160. return []
  161. }
  162. for(let i = 0;i < this.category.length;i++){
  163. let c = this.category[i]
  164. if(c.id == this.form.classId){
  165. return c.linkType ? c.linkType.split(',') : []
  166. // return 'code,phone,address,shop'.split(',')
  167. }
  168. }
  169. return []
  170. },
  171. },
  172. onLoad(args) {
  173. this.id = args.id
  174. this.form.classId = this.category[0].id
  175. // this.form.address = this.cityList[0].name
  176. this.imageMax = args.imageMax || 9
  177. this.getDateil()
  178. },
  179. onShow() {
  180. this.$store.commit('getCategory')
  181. },
  182. methods : {
  183. clickCategory(item, index){
  184. this.form.classId = item.id
  185. },
  186. clickAddress(item, index){
  187. this.form.address = item.name
  188. },
  189. getDateil(){
  190. if(!this.id){
  191. return
  192. }
  193. let self = this
  194. this.$api('getPostDetail', {
  195. id : this.id
  196. }, res => {
  197. if (res.code == 200) {
  198. self.form.id = res.result.id
  199. self.form.title = res.result.title
  200. self.form.address = res.result.address || self.form.address
  201. self.form.classId = res.result.classId || self.form.classId
  202. self.form.latitude = res.result.latitude || self.form.latitude
  203. self.form.longitude = res.result.longitude || self.form.longitude
  204. self.form.shop = res.result.shop || self.form.shop
  205. self.form.shopId = res.result.shopId || self.form.shopId
  206. if(res.result.wxImage){
  207. self.codeFileList = [
  208. {
  209. url : res.result.wxImage
  210. }
  211. ]
  212. }
  213. if(res.result.image){
  214. res.result.image.split(',')
  215. .forEach(url => {
  216. if(url.trim()){
  217. // 根据文件扩展名判断类型
  218. const isVideo = this.isVideoFile(url.trim())
  219. self.fileList.push({
  220. url: url.trim(),
  221. type: isVideo ? 'video' : 'image'
  222. })
  223. }
  224. })
  225. }
  226. }
  227. })
  228. },
  229. deleteImage(e){
  230. this[e.name].splice(e.index, 1)
  231. },
  232. afterRead(e){
  233. let self = this
  234. e.file.forEach(file => {
  235. // 检测文件类型
  236. const isVideo = this.isVideoFile(file.url || file.path)
  237. self.$Oss.ossUpload(file.url).then(url => {
  238. self[e.name].push({
  239. url,
  240. type: isVideo ? 'video' : 'image'
  241. })
  242. })
  243. })
  244. },
  245. // 检测是否为视频文件
  246. isVideoFile(filePath) {
  247. const videoExtensions = ['.mp4', '.avi', '.mov', '.wmv', '.flv', '.webm', '.m4v', '.3gp']
  248. const fileName = filePath.toLowerCase()
  249. return videoExtensions.some(ext => fileName.includes(ext))
  250. },
  251. // 提交
  252. submit(){
  253. // if(this.fileList.length == 0){
  254. // return uni.showToast({
  255. // title: '请上传图片',
  256. // icon : 'none'
  257. // })
  258. // }
  259. if (this.$utils.verificationAll(this.form, {
  260. title: '说点什么吧',
  261. })) {
  262. return
  263. }
  264. if(this.categoryRole.includes('code') && this.codeFileList.length == 0){
  265. return uni.showToast({
  266. title: '请上传微信二维码',
  267. icon : 'none'
  268. })
  269. }
  270. delete this.form.shop
  271. // 将所有文件(图片和视频)合并到 image 字段
  272. this.form.image = this.fileList.map((item) => item.url).join(",")
  273. this.form.wxImage = this.codeFileList.map((item) => item.url).join(",")
  274. this.$api('publishPost', this.form, res => {
  275. if(res.code == 200){
  276. uni.showToast({
  277. title: '发布成功!',
  278. icon: 'none'
  279. })
  280. setTimeout(uni.navigateBack, 1000, -1)
  281. }
  282. })
  283. },
  284. //地图上选择地址
  285. selectAddr() {
  286. Position.selectAddress(success => {
  287. this.setAddress(success)
  288. })
  289. },
  290. //提取用户选择的地址信息复制给表单数据
  291. setAddress(res) {
  292. //经纬度信息
  293. this.form.latitude = res.latitude
  294. this.form.longitude = res.longitude
  295. if (res.name) { //用户直接选择城市的逻辑
  296. // if (!res.address && res.name) { //用户直接选择城市的逻辑
  297. return this.form.address = res.name
  298. }
  299. // if (res.address || res.name) {
  300. // return this.form.address = res.address + res.name
  301. // }
  302. this.form.address = '' //用户啥都没选就点击勾选
  303. this.form.latitude = ''
  304. this.form.longitude = ''
  305. },
  306. // 选择关联的店铺
  307. selectShop(shop){
  308. this.form.shop = shop
  309. this.form.shopId = shop.id
  310. this.$refs.pickerHospital.close()
  311. },
  312. }
  313. }
  314. </script>
  315. <style lang="scss" scoped>
  316. .publishPost{
  317. background-color: #fff;
  318. min-height: 100vh;
  319. font-size: 28rpx;
  320. padding-bottom: 150rpx;
  321. /deep/ .uv-textarea{
  322. background-color: transparent;
  323. border: none;
  324. }
  325. /deep/ .uv-textarea__count{
  326. background-color: transparent !important;
  327. }
  328. .box{
  329. padding: 0 20rpx;
  330. }
  331. .images{
  332. display: flex;
  333. flex-wrap: wrap;
  334. padding: 20rpx;
  335. }
  336. .title-input{
  337. margin: 10rpx;
  338. border-bottom: 1px solid #00000015;
  339. padding-bottom: 25rpx;
  340. margin-bottom: 15rpx;
  341. display: flex;
  342. align-items: center;
  343. justify-content: space-between;
  344. input{
  345. width: 100%;
  346. }
  347. .shop-box{
  348. .title{
  349. font-size: 28rpx;
  350. }
  351. .desc{
  352. margin-top: 10rpx;
  353. color: #888;
  354. font-size: 24rpx;
  355. }
  356. }
  357. }
  358. .content-input{
  359. min-height: 400rpx;
  360. /deep/ .uv-textarea{
  361. min-height: 400rpx;
  362. }
  363. }
  364. .upTop{
  365. .title{
  366. padding-top: 20rpx;
  367. padding-left: 20rpx;
  368. border-top: 1px solid #00000015;
  369. display: flex;
  370. align-items: center;
  371. }
  372. .list{
  373. padding-top: 30rpx;
  374. width: 100%;
  375. .item{
  376. display: flex;
  377. padding: 20rpx;
  378. padding-left: 80rpx;
  379. justify-content: space-between;
  380. width: 600rpx;
  381. border-bottom: 1px solid #00000015;
  382. align-items: center;
  383. }
  384. }
  385. }
  386. .configBtn{
  387. padding: 20rpx;
  388. color: #777;
  389. padding-top: 40rpx;
  390. font-size: 28rpx;
  391. }
  392. .confirmationPopup{
  393. display: flex;
  394. flex-direction: column;
  395. align-items: center;
  396. justify-content: center;
  397. width: 100%;
  398. height: 300rpx;
  399. image{
  400. margin-top: 40rpx;
  401. }
  402. .info{
  403. margin-top: 40rpx;
  404. font-size: 26rpx;
  405. }
  406. }
  407. }
  408. .category{
  409. padding: 20rpx;
  410. .title{
  411. // font-weight: 900;
  412. // font-size: 30rpx;
  413. }
  414. .tagList{
  415. display: flex;
  416. flex-wrap: wrap;
  417. padding: 10rpx 0;
  418. view{
  419. background: rgba($uni-color, 0.1);
  420. padding: 10rpx 20rpx;
  421. margin: 10rpx;
  422. border-radius: 10rpx;
  423. font-size: 26rpx;
  424. }
  425. .act{
  426. color: #fff;
  427. background: $uni-color;
  428. }
  429. }
  430. }
  431. </style>