createFullscreenAd.vue 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008
  1. <template>
  2. <view class="page">
  3. <u-sticky :h5-nav-height="0" z-index="9099" :offset-top='0'>
  4. <uni-NavBar :headerTitle="`${headerTitle}创建`" background="#fff" :isSlot="false"></uni-NavBar>
  5. </u-sticky>
  6. <u-form :model="adForm" :rules="adrules" ref="uForm" :label-width="200"
  7. style="padding: 20rpx 24rpx 135rpx;box-sizing: border-box;">
  8. <view class="module">
  9. <text class="module-title ">基本信息</text>
  10. <u-form-item label="投放计划名称" prop="name" required>
  11. <u-input v-model="adForm.name" :custom-style="{textAlign:'right'}"
  12. placeholder="请输入...(最多20个字符)"></u-input>
  13. </u-form-item>
  14. <u-form-item label="选择广告位" prop="positionName" required :border-bottom="false">
  15. <u-input v-model="adForm.positionName" type="select" :select-open="adSlotShow"
  16. @click="adSlotShow=true" :custom-style="{textAlign:'right'}" placeholder="请选择"></u-input>
  17. </u-form-item>
  18. </view>
  19. <view class="module">
  20. <text class="module-title ">投放区域</text>
  21. <u-form-item label="门店地址" prop="address" required :border-bottom="false">
  22. <u-input v-model="adForm.address" type="textarea" disabled
  23. :custom-style="{textAlign:'right'}"></u-input>
  24. </u-form-item>
  25. <u-form-item label="投放范围" prop="coverageArea" required :border-bottom="false">
  26. <u-input v-model="adForm.coverageArea" type="number" :custom-style="{textAlign:'right'}"></u-input>
  27. <text class="ml-1">公里</text>
  28. </u-form-item>
  29. </view>
  30. <view class="module">
  31. <text class="module-title ">投放时间</text>
  32. <u-form-item label="投放开始时间" required prop="startDate">
  33. <u-input v-model="adForm.startDate" type="select" :select-open="startDateShow"
  34. @click="startDateShow=true" :custom-style="{textAlign:'right'}" placeholder="请选择"></u-input>
  35. </u-form-item>
  36. <u-form-item label="投放结束时间" required prop="endDate">
  37. <u-input v-model="adForm.endDate" type="select" :select-open="endDateShow" @click="endDateShow=true"
  38. :custom-style="{textAlign:'right'}" placeholder="请选择"></u-input>
  39. </u-form-item>
  40. <view class="dis f-c ">
  41. <u-form-item label="生效周期" prop="validPeriodType" required
  42. :border-bottom="adForm.validPeriodType && adForm.validPeriodType!='0'? false:true">
  43. <view class="dis a-c j-end" style="width: 100%;">
  44. <view class="tab-view dis a-c j-c"
  45. :class="{'tab-view-active':adForm.validPeriodType==item.value}"
  46. v-for="(item,index) in validPeriodTypeList" :key="index"
  47. @click="validPeriodTypeSelect(item)">
  48. <text>{{item.label}}</text>
  49. </view>
  50. </view>
  51. </u-form-item>
  52. <!-- 周期策略选择 -->
  53. <u-form-item prop="validPeriodValue" :border-bottom='false'
  54. v-if="adForm.validPeriodType && adForm.validPeriodType!='0'">
  55. <view class="extendArea dis a-c f-wrap" style="padding-bottom: 0;">
  56. <view class="cycleStrategy dis a-c j-c" v-for="(item,index) in cycleStrategylist"
  57. :key="index" :class="{ 'tcycleStrategy-active': selectedDays.includes(item.value) }"
  58. @click="toggleDaySelection(item.value)">
  59. <text>{{item.label}}</text>
  60. </view>
  61. </view>
  62. </u-form-item>
  63. </view>
  64. <view class="dis f-c ">
  65. <u-form-item label="生效时段" prop="validTimeRangeType" required :border-bottom="false">
  66. <view class="dis a-c j-end" style="width: 100%;">
  67. <view class="tab-view dis a-c j-c"
  68. :class="{'tab-view-active':adForm.validTimeRangeType==item.value}"
  69. v-for="(item,index) in validTimeRangeTypeList" :key="index"
  70. @click="timeSegmentSelect(item)">
  71. <text>{{item.label}}</text>
  72. </view>
  73. </view>
  74. </u-form-item>
  75. <view class="extendArea mb-3 " style="font-size: 26rpx;" v-if="adForm.validTimeRangeType=='1'">
  76. <view class=" dis a-c j-s mb-3">
  77. <text style="color: #333;">开始时间</text>
  78. <view class="dis a-c" @click="timeSegmentStartShow=true">
  79. <text style="color: #aaa;" class="mr-1">{{timeSegmentStart|| '请选择'}}</text>
  80. <u-icon name="arrow-right" color="#979797" size="26"></u-icon>
  81. </view>
  82. </view>
  83. <view class=" dis a-c j-s ">
  84. <text style="color: #333;">开始时间</text>
  85. <view class="dis a-c" @click="timeSegmentEndShow=true">
  86. <text style="color: #aaa;" class="mr-1">{{timeSegmentEnd || "请选择"}}</text>
  87. <u-icon name="arrow-right" color="#979797" size="26"></u-icon>
  88. </view>
  89. </view>
  90. </view>
  91. </view>
  92. </view>
  93. <view class="module">
  94. <text class="module-title ">投放内容</text>
  95. <!-- 图片上传 -->
  96. <view class="fileUpload ">
  97. <view class="tabs dis a-end" v-if="tabList.length>1">
  98. <view v-for="(item, index) in tabList" :key="index" class="tab dis a-c j-c" :class="{
  99. active: fileUploadActiveTab === index,
  100. tab1: fileUploadActiveTab !== index,
  101. left: fileUploadActiveTab === 0,
  102. right: fileUploadActiveTab === 1
  103. }" @click="handleTab(index,item)">
  104. <view class="tabtitle">
  105. <view class="">
  106. {{ item.label }}
  107. </view>
  108. </view>
  109. </view>
  110. </view>
  111. <view class="fileUploadView" v-if="adForm.imageType=='1'">
  112. <view class="p-2" v-show="imgFileList.length>0">
  113. <u-upload ref="Upload" :file-list="imgFileList" :action="action"
  114. @on-list-change="onListChange" @on-success="detailsSuccess" :source-type="['album']"
  115. width="150" height="150">
  116. </u-upload>
  117. </view>
  118. <view class="default dis f-c a-c j-c " @click="triggerUpload" v-if="!imgFileList.length">
  119. <image src="/static/ad/ggtp.png" mode=""></image>
  120. <text class="title">请上传广告图片</text>
  121. <text>
  122. 尺寸建议:建议图片1125*2436px,支持jpg、png格式,体积小于1Mb。因手机分辨率问题,部分机型可能图片展示不全,重要信息尽量展示在图片中部。
  123. </text>
  124. </view>
  125. </view>
  126. <view class="fileUploadView" v-if="adForm.imageType=='2'">
  127. <view class="p-2 dis f-c " v-if="adForm.taskImage">
  128. <video id="myVideo" :src="adForm.taskImage" :style="{width:'100%',height:'330rpx'}"
  129. :muted="false" :enable-progress-gesture="true">
  130. </video>
  131. <view class="dis a-c j-end mt-2" style="width: 100%;">
  132. <u-button size="medium" type="primary" plain style="margin-left: auto;"
  133. @click="videoDel">删除</u-button>
  134. </view>
  135. </view>
  136. <view class="default dis f-c a-c j-c " @click="uploadVideo" v-else>
  137. <image src="/static/ad/ggsp.png" mode=""></image>
  138. <text class="title">请上传广告视频</text>
  139. <text>尺寸建议:画面比例9:16,支持MP4格式,时长小于等于30秒。因手机分辨率问题,部分机型可能画面展示不全,重要信息尽量展示在画面中部。</text>
  140. </view>
  141. </view>
  142. </view>
  143. </view>
  144. <view class="module" v-if="adPricingModelList.length>0">
  145. <text class="module-title">计费方式</text>
  146. <u-radio-group v-model="adForm.relId" :wrap="true" active-color="#4B9DFF">
  147. <view class="dis a-c j-c BillingModelView" v-for="(item, index) in adPricingModelList" :key="index">
  148. <u-radio :name="item.id" label-size="26">
  149. <text style="margin-right: 60rpx;">{{item.pricingName}}</text>
  150. <text>{{ item.amount }} {{ item.pricingUnit }}</text>
  151. </u-radio>
  152. </view>
  153. </u-radio-group>
  154. </view>
  155. <view class="module">
  156. <text class="module-title ">投放频次</text>
  157. <view class="deliveryFrequency dis a-c ">
  158. <view class="title">每人每天展示次数</view>
  159. <u-radio-group v-model="userDailyImpCount" @change="userDailyImpCountChange" active-color="#4B9DFF">
  160. <u-radio name="1" label-size="26">不限</u-radio>
  161. <u-radio name="2" label-size="26">限制</u-radio>
  162. </u-radio-group>
  163. <view class="dis a-c flex-1" v-if="userDailyImpCount=='2'">
  164. <u-input v-model="adForm.userDailyDisplayLimit" :custom-style="{width:'100rpx',minHeight:'0'}"
  165. placeholder="请输入"></u-input>
  166. <text>次</text>
  167. </view>
  168. </view>
  169. <view class="deliveryFrequency dis a-c ">
  170. <view class="title">每人展示次数</view>
  171. <u-radio-group v-model="userImpCount" @change="userImpCountChange" active-color="#4B9DFF">
  172. <u-radio name="1" label-size="26">不限</u-radio>
  173. <u-radio name="2" label-size="26">限制</u-radio>
  174. </u-radio-group>
  175. <view class="dis a-c flex-1" v-if="userImpCount=='2'">
  176. <u-input v-model="adForm.userTotalDisplayLimit" :custom-style="{width:'50rpx',minHeight:'0'}"
  177. placeholder="请输入"></u-input>
  178. <text>次</text>
  179. </view>
  180. </view>
  181. <view class="deliveryFrequency dis a-c ">
  182. <view class="title">展示时间间隔</view>
  183. <u-radio-group v-model="displayTimeInterval" @change="displayTimeIntervalChange"
  184. active-color="#4B9DFF">
  185. <u-radio name="1" label-size="26">不限</u-radio>
  186. <u-radio name="2" label-size="26">限制</u-radio>
  187. </u-radio-group>
  188. <view class="dis a-c flex-1" v-if="displayTimeInterval=='2'">
  189. <u-input v-model="adForm.showInterval" :custom-style="{width:'50rpx',minHeight:'0'}"
  190. placeholder="请输入"></u-input>
  191. <text>分钟</text>
  192. </view>
  193. </view>
  194. </view>
  195. <view class="module">
  196. <text class="module-title ">广告预算</text>
  197. <u-form-item label="广告预算" prop="adBudget" required :border-bottom="false">
  198. <u-input v-model="adForm.adBudget" :custom-style="{textAlign:'right'}"></u-input>
  199. <text class="ml-1">元</text>
  200. </u-form-item>
  201. <text class="mb-3" style="font-size: 22rpx;color: #aaa;">为保证广告正常投放,请保证余额账户有充足余额,余额不足时,广告 将自动暂停投放。</text>
  202. </view>
  203. </u-form>
  204. <view class="footer-view">
  205. <view class="dis a-c j-c " @click="submit">
  206. 提交审核
  207. </view>
  208. </view>
  209. <!-- 广告位 -->
  210. <u-select v-model="adSlotShow" mode="single-column" label-name="positionName" value-name="id" :list="adSlotList"
  211. @confirm="adSlotConfirm"></u-select>
  212. <!-- 投放日期 -->
  213. <u-calendar v-model="startDateShow" mode="date" @change="startDateChange" max-date="2050-12-31"></u-calendar>
  214. <u-calendar v-model="endDateShow" mode="date" @change="endDateChange" max-date="2050-12-31"></u-calendar>
  215. <!-- 投放时间 -->
  216. <u-picker v-model="timeSegmentStartShow" mode="time" :params="params"
  217. @confirm="timeSegmentStartConfirm"></u-picker>
  218. <u-picker v-model="timeSegmentEndShow" mode="time" :params="params" @confirm="timeSegmentEndConfirm"></u-picker>
  219. <!-- 自定义加载动画 -->
  220. <u-mask :show="lodingShow" style="background-color: rgba(255, 255, 255, 0.6);">
  221. <view class="dis a-c j-c " style="height: 100%;">
  222. <u-loading mode="circle"></u-loading>
  223. </view>
  224. </u-mask>
  225. </view>
  226. </template>
  227. <script>
  228. import {
  229. ACCESS_TOKEN,
  230. USER_INFO
  231. } from '@/common/util/constants.js'
  232. import {
  233. getCity,
  234. findCityCodeByCname
  235. } from './parseAddress.js' //地址解析函数
  236. import configService from '@/common/service/config.service'
  237. export default {
  238. data() {
  239. return {
  240. adSlotPriceList: [], //价格列表
  241. adPricingModelList: [], //计费模式列表
  242. queryTreeList: [], //省市区optinos
  243. adSlotList: [], //广告位options
  244. queryTreeValue: "", //省市区回显
  245. lodingShow: false, //loding组件
  246. startDateShow: false, //开始日期选择
  247. endDateShow: false, //结束日期选择
  248. queryTreeShow: false, //省市区选择
  249. adSlotShow: false, //广告位选择
  250. timeSegmentStartShow: false, //开始时间
  251. timeSegmentEndShow: false, //结果时间
  252. params: {
  253. year: false,
  254. month: false,
  255. day: false,
  256. hour: true,
  257. minute: true,
  258. second: true
  259. },
  260. value: 'orange',
  261. value1: "",
  262. adForm: {
  263. id: "",
  264. name: '', //投放计划名称
  265. positionId: null, //广告位id
  266. positionName: "", //广告位name
  267. startDate: "", //投放开始时间
  268. endDate: "", //投放结束时间
  269. city: "", //市
  270. validPeriodType: "", //生效周期
  271. validPeriodValue: "", //周期策略
  272. validTimeRangeType: "", //生效时段类型
  273. validTimeRangeValue: "", //生效时段值
  274. relId: "", //计费方式
  275. userDailyDisplayLimit: "", //每人每天展示次数
  276. userTotalDisplayLimit: "", //每人总次数
  277. showInterval: "", //展示时间间隔
  278. taskImage: "", //文件路径
  279. imageType: "1", //文件类型
  280. type: "", //广告类型
  281. adBudget: "", //广告预算
  282. merchantId: "", //商户id
  283. merchantName: "", //商户name
  284. address: "",
  285. longitude: "", //经度
  286. latitude: "", //维度
  287. coverageArea: 0, //范围
  288. },
  289. timeSegmentStart: "", //生效时段开始
  290. timeSegmentEnd: "", //生效时段结束
  291. userDailyImpCount: "1",
  292. userImpCount: "1",
  293. displayTimeInterval: "1",
  294. adrules: {
  295. name: [{
  296. required: true,
  297. message: '请输入名称',
  298. trigger: ['change', 'blur'],
  299. }],
  300. positionName: [{
  301. required: true,
  302. message: '请选择广告位',
  303. trigger: ['change', 'blur'],
  304. }],
  305. district: [{
  306. required: true,
  307. message: '请选择投放区域',
  308. trigger: ['change', 'blur'],
  309. }],
  310. startDate: [{
  311. required: true,
  312. message: '时间必选',
  313. trigger: ['change', 'blur'],
  314. }],
  315. endDate: [{
  316. required: true,
  317. message: '时间必选',
  318. trigger: ['change', 'blur'],
  319. }],
  320. validPeriodType: [{
  321. required: true,
  322. message: '生效周期必选',
  323. trigger: ['blur'],
  324. }],
  325. validTimeRangeType: [{
  326. required: true,
  327. message: '生效时段必传',
  328. trigger: ['blur'],
  329. }],
  330. adBudget: [{
  331. required: true,
  332. message: '广告预算必填',
  333. trigger: ['blur'],
  334. }],
  335. taskImage: [{
  336. required: true,
  337. message: '投放内容必传',
  338. trigger: ['change'],
  339. }],
  340. validPeriodValue: [{
  341. required: true,
  342. message: '生效周期至少选择一天',
  343. trigger: ['change'],
  344. }],
  345. },
  346. weekList: [], //周
  347. monthList: [], //月
  348. selectedDays: [], //周期策略选中日期
  349. timeSegment: "", //生效时段
  350. validTimeRangeTypeList: [{
  351. label: "全天",
  352. value: "0",
  353. },
  354. {
  355. label: "指定时间段",
  356. value: "1",
  357. },
  358. ],
  359. //生效周期
  360. validPeriodTypeList: [{
  361. label: "每天",
  362. value: "0",
  363. },
  364. {
  365. label: "每周",
  366. value: "1",
  367. },
  368. {
  369. label: "每月",
  370. value: "2",
  371. }
  372. ],
  373. tabList: [],
  374. fileUploadActiveTab: 0,
  375. //文件回显列表
  376. imgFileList: [], //图片数组
  377. action: configService.apiUrl + '/sys/common/upload', //图片上传地址
  378. token: "",
  379. userInfo: {},
  380. headerTitle: "", //页面标题
  381. }
  382. },
  383. onShow() {},
  384. async onLoad(options) {
  385. if (options.adType) {
  386. this.adForm.type = options.adType;
  387. const map = {
  388. '0': '全屏广告',
  389. '1': '弹窗广告',
  390. '2': '轮播广告',
  391. '3': '页面嵌入广告',
  392. }
  393. this.headerTitle = map[this.adForm.type] || ''
  394. }
  395. if (options.id) {
  396. this.$http.get('advert/localAdvertTask/queryById?id=' + options.id).then(res => {
  397. if (res.data.code == '200') {
  398. delete res.data.result.adPositionPriceRel
  399. delete res.data.result.createBy;
  400. delete res.data.result.createTime;
  401. delete res.data.result.isDelete;
  402. delete res.data.result.updateBy;
  403. delete res.data.result.updateTime;
  404. this.adForm = res.data.result
  405. this.queryTreeValue =
  406. `${this.adForm.province}-${this.adForm.city}-${this.adForm.district}-${this.adForm.street}`;
  407. this.getadBillingModel();
  408. this.selectedDays = this.adForm.validPeriodValue.split(',')
  409. let list = this.adForm.validTimeRangeValue.split(',');
  410. this.timeSegmentStart = list[0];
  411. this.timeSegmentEnd = list[1];
  412. let imglist = this.adForm.taskImage.split(",")
  413. this.imgFileList = imglist.map(val => {
  414. return {
  415. url: val
  416. }
  417. })
  418. if (this.adForm.userDailyDisplayLimit) {
  419. this.userDailyImpCount = '2';
  420. }
  421. if (this.adForm.userTotalDisplayLimit) {
  422. this.userImpCount = '2';
  423. }
  424. if (this.adForm.showInterval) {
  425. this.displayTimeInterval = '2';
  426. }
  427. this.adForm.validTimeRangeType = this.adForm.validTimeRangeType + '';
  428. this.adForm.validPeriodType = this.adForm.validPeriodType + '';
  429. this.adForm.adBudget = this.adForm.adBudget + '';
  430. console.log(this.adForm);
  431. }
  432. })
  433. }
  434. this.token = uni.getStorageSync(ACCESS_TOKEN);
  435. this.userInfo = uni.getStorageSync(USER_INFO);
  436. this.adForm.merchantId = this.userInfo.merchantId;
  437. this.adForm.merchantName = this.userInfo.merchantName;
  438. await this.queryTree(); //获取省市区数据
  439. await this.queryAdSlot(); // 获取广告位数据
  440. this.generateWeek();
  441. this.generatemonth();
  442. this.storeDetail();
  443. },
  444. onReady() {
  445. this.$refs.uForm.setRules(this.adrules);
  446. },
  447. computed: {
  448. //区分月和周
  449. cycleStrategylist() {
  450. return this.adForm.validPeriodType == '1' ? this.weekList : this.monthList;
  451. }
  452. },
  453. methods: {
  454. // 门店
  455. async storeDetail() {
  456. let id = uni.getStorageSync(USER_INFO).merchantId;
  457. let res = await this.$http.get("/merchant/localMerchantInfo/queryAppInfoById?id=" + id)
  458. if (res.data.success) {
  459. console.log(res);
  460. this.adForm.address = res.data.result.address;
  461. this.adForm.longitude = Number(res.data.result.longitude);
  462. this.adForm.latitude = Number(res.data.result.latitude);
  463. const addressResult = getCity(this.adForm.address); //截取城市
  464. const cityCode = findCityCodeByCname(addressResult, this.queryTreeList) // 查找城市code
  465. this.adForm.city = cityCode;
  466. }
  467. },
  468. submit() {
  469. if (this.adForm.validTimeRangeType == '1' && this.timeSegmentStart && this.timeSegmentEnd) {
  470. this.adForm.validTimeRangeValue = this.timeSegmentStart + "," + this.timeSegmentEnd;
  471. }
  472. console.log(this.adForm);
  473. this.$refs.uForm.validate(valid => {
  474. if (valid) {
  475. if (!this.adForm.taskImage) {
  476. return uni.showToast({
  477. title: "素材不能为空",
  478. icon: 'none'
  479. })
  480. }
  481. if (!this.timeSegmentStart && this.timeSegmentEnd) {
  482. return uni.showToast({
  483. title: "生效时间段补充完整",
  484. icon: 'none'
  485. })
  486. }
  487. if (this.adForm.id) {
  488. this.$http.post('advert/localAdvertTask/merchantEdit', this.adForm).then(res => {
  489. if (res.data.code == '200') {
  490. uni.showToast({
  491. title: res.data.message,
  492. icon: "none"
  493. })
  494. uni.navigateBack({
  495. delta: 1
  496. });
  497. }
  498. })
  499. } else {
  500. this.$http.post('advert/localAdvertTask/merchantAdd', this.adForm).then(res => {
  501. if (res.data.code == '200') {
  502. uni.showToast({
  503. title: res.data.message,
  504. icon: "none"
  505. })
  506. uni.navigateBack({
  507. delta: 1
  508. });
  509. }
  510. })
  511. }
  512. } else {
  513. console.log('验证失败');
  514. }
  515. });
  516. },
  517. videoDel() {
  518. this.adForm.taskImage = "";
  519. },
  520. //视频上传
  521. async uploadVideo(type, imageIdList, imgurl) {
  522. let [chooseImageErr, chooseImageRes] = await uni.chooseVideo({
  523. sourceType: ['album']
  524. });
  525. if (chooseImageRes) {
  526. uni.uploadFile({
  527. url: configService.apiUrl + '/sys/common/upload',
  528. name: "file",
  529. file: chooseImageRes.tempFile,
  530. header: {
  531. Authorization: this.token,
  532. },
  533. success: async (Res) => {
  534. let data = JSON.parse(Res.data);
  535. this.adForm.taskImage = configService.apiUrl + '/' + data.message;
  536. console.log(this.adForm.taskImage);
  537. },
  538. });
  539. }
  540. },
  541. triggerUpload() {
  542. this.$refs.Upload.selectFile(); // ref调用文件选择*****************************
  543. },
  544. //图片上传事件
  545. detailsSuccess(res, index, lists) {
  546. const fileList = lists.map((file) => {
  547. if (file.response) {
  548. // 拼接地址前缀
  549. file.url = configService.apiUrl + '/' + file.response.message;
  550. }
  551. return file.url;
  552. });
  553. this.adForm.taskImage = fileList.join(",") //图片地址逗号拼接
  554. this.imgFileList = lists;
  555. },
  556. //图片多选上传
  557. onListChange(lists) {
  558. },
  559. handleTab(index, item) {
  560. this.fileUploadActiveTab = index
  561. this.adForm.imageType = item.value;
  562. this.adForm.taskImage = "";
  563. this.imgFileList = [];
  564. },
  565. getadBillingModel() {
  566. this.$http.get('/adPricingPrice/queryPageList', {
  567. params: {
  568. adPositionId: this.adForm.positionId,
  569. city: this.adForm.city,
  570. pageNo: 1,
  571. pageSize: 1000,
  572. }
  573. }).then(res => {
  574. if (res.data.result.records.length > 0) {
  575. this.adSlotPriceList = res.data.result.records[0]?.adPositionPriceRelList;
  576. this.$http.get('/adPricingModel/queryPageList', {
  577. params: {
  578. pageNo: 1,
  579. pageSize: 1000,
  580. isDelete: 0,
  581. }
  582. }).then(res => {
  583. const pricingUnitMap = {
  584. "1": "元/点击",
  585. "2": "元/天",
  586. "3": "元/笔销售",
  587. "4": "元/千次曝光",
  588. }
  589. this.adPricingModelList = res.data.result.records.map(val => {
  590. return {
  591. adPricingModelId: val.id,
  592. pricingName: val.pricingName,
  593. pricingUnit: pricingUnitMap[val.pricingUnit],
  594. checked: false,
  595. amount: "",
  596. }
  597. })
  598. const result = this.adPricingModelList.map(model => {
  599. const matchedPrice = this.adSlotPriceList.find(price => price
  600. .adPricingModelId === model.adPricingModelId);
  601. return {
  602. ...model,
  603. amount: matchedPrice ? matchedPrice.amount : model.amount,
  604. checked: false,
  605. id: matchedPrice?.id,
  606. };
  607. }).filter(val => val.amount)
  608. this.adPricingModelList = result;
  609. })
  610. } else {
  611. uni.showToast({
  612. icon: "none",
  613. title: "该区域暂无计费模式相关配置"
  614. })
  615. }
  616. })
  617. },
  618. queryAdSlot() {
  619. this.$http.get('/adPosition/queryPageList').then(res => {
  620. if (res.data.code == 200) {
  621. if (res.data.code == 200) {
  622. this.adSlotList = res.data.result.records
  623. console.log(res.data.result);
  624. }
  625. }
  626. })
  627. },
  628. queryTree() {
  629. this.lodingShow = true;
  630. this.$http.post('/sys/area/queryTree').then(res => {
  631. if (res.data.code == 200) {
  632. console.log(res);
  633. this.queryTreeList = res.data.result
  634. this.lodingShow = false;
  635. }
  636. })
  637. },
  638. //广告位选择后续操作
  639. adSlotConfirm(value) {
  640. let info = this.adSlotList.find(val => val.id == value[0].value).supportMaterial.split(','); //获取投放内容类型
  641. if (info.length > 1) {
  642. this.tabList = info.map(val => {
  643. return {
  644. label: val == 1 ? '图片' : '视频',
  645. value: val
  646. }
  647. })
  648. } else {
  649. this.tabList = [];
  650. }
  651. this.adForm.imageType = info[0];
  652. this.adForm.positionId = value[0].value;
  653. this.adForm.positionName = value[0].label;
  654. this.getadBillingModel() //获取计费方式
  655. },
  656. //日期选择
  657. startDateChange(e) {
  658. this.adForm.startDate = e.result + " 00:00:00"
  659. },
  660. endDateChange(e) {
  661. this.adForm.endDate = e.result + " 23:59:59"
  662. },
  663. // 时间选择
  664. timeSegmentStartConfirm(value) {
  665. this.timeSegmentStart = `${value.hour}:${value.minute}:${value.second}`
  666. },
  667. timeSegmentEndConfirm(value) {
  668. this.timeSegmentEnd = `${value.hour}:${value.minute}:${value.second}`
  669. },
  670. userDailyImpCountChange(value) {
  671. if (value == 1) {
  672. this.adForm.userDailyDisplayLimit = ' ';
  673. } else {
  674. this.adForm.userDailyDisplayLimit = '';
  675. }
  676. },
  677. userImpCountChange(value) {
  678. if (value == 1) {
  679. this.adForm.userTotalDisplayLimit = ' ';
  680. } else {
  681. this.adForm.userTotalDisplayLimit = '';
  682. }
  683. },
  684. displayTimeIntervalChange(value) {
  685. if (value == 1) {
  686. this.adForm.showInterval = ' ';
  687. } else {
  688. this.adForm.showInterval = '';
  689. }
  690. },
  691. //周列表
  692. generateWeek() {
  693. const weekList = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'].map((val, index) => {
  694. return {
  695. label: val,
  696. value: (index + 1).toString()
  697. }
  698. })
  699. this.weekList = weekList;
  700. },
  701. // 月列表
  702. generatemonth() {
  703. const monthList = Array.from({
  704. length: 31
  705. }, (_, index) => {
  706. const value = (index + 1).toString();
  707. return {
  708. label: value,
  709. value
  710. };
  711. });
  712. this.monthList = monthList;
  713. },
  714. // 周期策略选择
  715. toggleDaySelection(dayValue) {
  716. const index = this.selectedDays.indexOf(dayValue);
  717. if (index > -1) {
  718. // 如果找到,移除该元素
  719. this.selectedDays.splice(index, 1);
  720. } else {
  721. // 如果未找到,添加该元素
  722. this.selectedDays.push(dayValue);
  723. }
  724. this.adForm.validPeriodValue = this.selectedDays.join(',')
  725. },
  726. //生效周期选择
  727. validPeriodTypeSelect(item) {
  728. this.adForm.validPeriodType = item.value
  729. this.selectedDays = [];
  730. },
  731. timeSegmentSelect(item) {
  732. this.adForm.validTimeRangeType = item.value
  733. if (item.value == 0) {
  734. this.adForm.validTimeRangeValue = "00:00:00,23:59:59"
  735. } else {
  736. this.adForm.validTimeRangeValue = "";
  737. this.timeSegmentStart = "";
  738. this.timeSegmentEnd = "";
  739. }
  740. }
  741. }
  742. }
  743. </script>
  744. <style lang="scss" scoped>
  745. .page {
  746. background-color: #F7F8FC;
  747. }
  748. .module {
  749. width: 100%;
  750. background: #FFFFFF;
  751. border-radius: 10rpx;
  752. padding: 30rpx 30rpx 0;
  753. box-sizing: border-box;
  754. margin-bottom: 20rpx;
  755. display: flex;
  756. flex-direction: column;
  757. .module-title {
  758. font-size: 34rpx;
  759. color: #333;
  760. font-weight: bold;
  761. }
  762. .tab-view {
  763. background: #FFFFFF;
  764. border-radius: 10rpx;
  765. border: 1px solid #E5E5E5;
  766. font-size: 26rpx;
  767. color: #333;
  768. padding: 10rpx 32rpx;
  769. box-sizing: border-box;
  770. margin-left: 20rpx;
  771. text {
  772. line-height: 1;
  773. }
  774. }
  775. .tab-view-active {
  776. background: #E0EDFF;
  777. color: #006DFF;
  778. border: 1rpx solid #E0EDFF;
  779. }
  780. .extendArea {
  781. padding: 20rpx 20rpx;
  782. box-sizing: border-box;
  783. background: #F6F8FC;
  784. border-radius: 10rpx;
  785. }
  786. .cycleStrategy {
  787. min-width: 100rpx;
  788. background: #FFFFFF;
  789. border-radius: 10rpx;
  790. border: 1px solid #E5E5E5;
  791. font-size: 26rpx;
  792. color: #333;
  793. padding: 10rpx 32rpx;
  794. box-sizing: border-box;
  795. margin-left: 20rpx;
  796. margin-bottom: 20rpx;
  797. text {
  798. line-height: 1;
  799. }
  800. }
  801. .tcycleStrategy-active {
  802. background: #E0EDFF;
  803. color: #006DFF;
  804. border: 1rpx solid #E0EDFF;
  805. }
  806. //计费模式
  807. .BillingModelView {
  808. width: 100%;
  809. border-bottom: 1rpx solid #eee;
  810. padding: 32rpx 0;
  811. box-sizing: border-box;
  812. }
  813. .deliveryFrequency {
  814. padding: 32rpx 0;
  815. box-sizing: border-box;
  816. border-bottom: 1rpx solid #eee;
  817. .title {
  818. font-size: 26rpx;
  819. color: #333;
  820. width: 250rpx;
  821. }
  822. }
  823. .deliveryFrequency:last-child {
  824. border-bottom: none;
  825. }
  826. }
  827. ::v-deep {
  828. .u-radio__label {
  829. color: #333;
  830. }
  831. // 图片上传预览视图层级提升
  832. }
  833. .uni-system-preview-image {
  834. background: #4B9DFF !important;
  835. z-index: 9999 !important;
  836. }
  837. .footer-view {
  838. z-index: 99;
  839. position: fixed;
  840. bottom: 0;
  841. left: 0;
  842. right: 0;
  843. background-color: #fff;
  844. padding: 17rpx 24rpx;
  845. box-sizing: border-box;
  846. box-shadow: 0rpx 0rpx 12rpx 1rpx rgba(225, 225, 225, 0.3);
  847. >view {
  848. width: 100%;
  849. padding: 26rpx;
  850. box-sizing: border-box;
  851. background: #4B9DFF;
  852. border-radius: 40rpx;
  853. font-size: 30rpx;
  854. color: #fff;
  855. }
  856. }
  857. .fileUpload {
  858. position: relative;
  859. width: 100%;
  860. margin: 0 auto;
  861. box-sizing: border-box;
  862. border-radius: 0px 10rpx 10rpx 10rpx;
  863. margin: 30rpx 0;
  864. .tabs {
  865. display: flex;
  866. position: relative;
  867. overflow: hidden;
  868. border-radius: 10rpx 10rpx 0 0;
  869. }
  870. .tab {
  871. flex: 1;
  872. height: 70rpx;
  873. color: #333;
  874. font-size: 30rpx;
  875. position: relative;
  876. border-top-right-radius: 10rpx;
  877. border-top-left-radius: 10rpx;
  878. &.active {
  879. background: #F6F8FC;
  880. color: #006DFF;
  881. font-size: 30rpx;
  882. border-top-right-radius: 10rpx;
  883. border-top-left-radius: 10rpx;
  884. }
  885. &.left.active {
  886. border-top-right-radius: 0;
  887. &::after {
  888. content: "";
  889. position: absolute;
  890. top: 0;
  891. right: -50px;
  892. height: 100%;
  893. width: 50px;
  894. z-index: 2;
  895. background-color: #F6F8FC;
  896. clip-path: path("M0 0 C13.5 0 13.5 25 25 45 L0 50 Z");
  897. }
  898. }
  899. // 右侧标签的曲线
  900. &.right.active {
  901. border-top-left-radius: 0;
  902. &::before {
  903. content: "";
  904. position: absolute;
  905. top: 0;
  906. left: -49px;
  907. height: 100%;
  908. width: 50px;
  909. z-index: 2;
  910. background-color: #F6F8FC;
  911. clip-path: path("M50 0 C37.5 0 37.5 25 25 45 L50 50 Z");
  912. }
  913. }
  914. }
  915. .tab1 {
  916. flex: 1;
  917. height: 70rpx;
  918. position: relative;
  919. border-top-right-radius: 10rpx;
  920. border-top-left-radius: 10rpx;
  921. background-color: #EBF2FA;
  922. }
  923. // 文件区域样式
  924. .tabtitle {
  925. position: relative;
  926. z-index: 1; // 父级降低层级
  927. font-size: 28rpx;
  928. }
  929. }
  930. .fileUploadView {
  931. width: 100%;
  932. background-color: #F6F8FC;
  933. border-radius: 10rpx 10rpx 10rpx 10rpx;
  934. min-height: 330rpx;
  935. .default {
  936. min-height: 330rpx;
  937. padding: 30rpx 40rpx;
  938. box-sizing: border-box;
  939. image {
  940. width: 83rpx;
  941. height: 74rpx;
  942. }
  943. text {
  944. font-size: 26rpx;
  945. color: #333;
  946. }
  947. .title {
  948. margin: 15rpx 0 40rpx;
  949. }
  950. text:last-child {
  951. font-size: 22rpx;
  952. color: #aaa;
  953. }
  954. }
  955. }
  956. </style>