groupCreate.vue 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160
  1. <template>
  2. <a-card :body-style="{padding: '24px 32px'}" :bordered="false">
  3. <a-form @submit="handleSubmit" :form="form">
  4. <a-form-item
  5. label="选择快手账户"
  6. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  7. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  8. <a-select
  9. @change="deepConversion"
  10. v-model="accountId"
  11. showSearch
  12. showArrow
  13. allowClear
  14. placeholder="选择需创建的快手账户"
  15. optionFilterProp="children"
  16. style="width: 500px"
  17. :filterOption="filterOption"
  18. >
  19. <a-select-option v-for="userAccount in accountList" :key="userAccount.accountId"
  20. :value="userAccount.accountId">{{userAccount.authName}}
  21. </a-select-option>
  22. </a-select>
  23. </a-form-item>
  24. <a-form-item
  25. label="选择广告计划模板"
  26. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  27. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  28. <a-select
  29. v-model="campaignTemplateId"
  30. showSearch
  31. showArrow
  32. placeholder="请选择广告计划模板"
  33. optionFilterProp="children"
  34. style="width: 500px"
  35. :filterOption="filterOption"
  36. >
  37. <a-select-option v-for="campaign in campaignList" :key="campaign.id"
  38. :value="campaign.id">{{campaign.campaignName}}
  39. </a-select-option>
  40. </a-select>
  41. </a-form-item>
  42. <a-form-item
  43. label="请选择目标人群"
  44. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  45. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  46. <a-select
  47. v-model="targetPopulation"
  48. showSearch
  49. showArrow
  50. disabled
  51. placeholder="请选择目标人群"
  52. optionFilterProp="children"
  53. style="width: 500px"
  54. :filterOption="filterOption"
  55. >
  56. <a-select-option value="default">请期待</a-select-option>
  57. </a-select>
  58. </a-form-item>
  59. <a-form-item
  60. label="单日预算"
  61. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  62. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  63. <a-radio-group buttonStyle="solid" @change="showBudgetStatusChange" v-model="campaignBudget">
  64. <a-radio-button value="UNLIMITED">不限</a-radio-button>
  65. <a-radio-button value="AS_BUDGET">统一预算</a-radio-button>
  66. </a-radio-group>
  67. </a-form-item>
  68. <a-form-item
  69. label="预算金额"
  70. v-if="showBudgetDaily"
  71. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  72. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  73. <a-input
  74. v-model="dayBudget"
  75. v-decorator="[
  76. 'confirm_dayBudget',
  77. {rules: [{ required: true, message: ' ' },
  78. {validator: handleConfirmValue}]}
  79. ]"
  80. placeholder="不小于500,不超过100000000,仅支持输入自然数" type="number" style="width: 70%"></a-input>
  81. </a-form-item>
  82. <a-form-item
  83. label="投放方式"
  84. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  85. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  86. <a-radio-group v-model="speed">
  87. <a-radio-button value='1'>快速投放</a-radio-button>
  88. <a-radio-button value='2'>平滑投放</a-radio-button>
  89. </a-radio-group>
  90. </a-form-item>
  91. <a-form-item
  92. label="排期"
  93. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  94. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  95. <a-radio-group buttonStyle="solid" v-model="schedulingType" @change="showSetDate">
  96. <a-radio-button value='1'>从今天开始长期投放</a-radio-button>
  97. <a-radio-button value='2'>设置开始和结束日期</a-radio-button>
  98. </a-radio-group>
  99. </a-form-item>
  100. <a-form-item label="设置时间"
  101. v-if="showTime"
  102. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  103. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  104. <a-range-picker
  105. name="buildTime"
  106. style="width: 100%"
  107. v-model="time"/>
  108. </a-form-item>
  109. <a-form-item
  110. label="投放时段"
  111. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  112. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  113. <a-radio-group buttonStyle="solid" v-model="scheduleTimeType" @change="showSetScheduleTime">
  114. <a-radio-button value='1'>全天</a-radio-button>
  115. <a-radio-button value='2'>特定时间</a-radio-button>
  116. </a-radio-group>
  117. </a-form-item>
  118. <a-form-item
  119. label="设置时间段"
  120. v-if="showScheduleTime"
  121. v-model="scheduleTime"
  122. :labelCol="{lg: {span: 7}, sm: {span: 20}}"
  123. :wrapperCol="{lg: {span: 15}, sm: {span: 16} }">
  124. <div id="table_time_selected1" class="table_time_selected1">
  125. </div>
  126. </a-form-item>
  127. <a-form-item
  128. label="创意展现方式"
  129. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  130. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  131. <a-radio-group v-model="showMode">
  132. <a-radio-button value='2'>优先</a-radio-button>
  133. <a-radio-button value='1'>轮播</a-radio-button>
  134. </a-radio-group>
  135. </a-form-item>
  136. <a-form-item
  137. label="优化目标出价类型"
  138. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  139. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  140. <a-radio-group v-model="bidType" buttonStyle="solid" @change="showBidType">
  141. <a-radio-button value='2'>CPC</a-radio-button>
  142. <a-radio-button value='20'>ECPC</a-radio-button>
  143. <a-radio-button value='6'>OCPC</a-radio-button>
  144. </a-radio-group>
  145. </a-form-item>
  146. <a-form-item
  147. label="出价"
  148. v-if="showBid"
  149. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  150. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  151. <a-input
  152. v-model="bid"
  153. v-decorator="[
  154. 'confirm_bid',
  155. {rules: [{ required: true, message: ' ' },
  156. {validator: handleConfirmBid}]}
  157. ]"
  158. placeholder="不低于0.2元,不高于100元" style="width: 70%"></a-input>
  159. </a-form-item>
  160. <a-form-item
  161. label="优化目标"
  162. v-if="showOcpxActionType"
  163. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  164. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  165. <a-radio-group v-model="ocpxActionType" @change="showBidType">
  166. <a-radio-button value="2">行为数</a-radio-button>
  167. <a-radio-button value="180" :disabled="activationDisabled">激活</a-radio-button>
  168. <a-radio-button value="53" :disabled="isFormDisabled">表单转化</a-radio-button>
  169. </a-radio-group>
  170. </a-form-item>
  171. <a-form-item
  172. label="OCPC出价"
  173. v-if="showCpaBid"
  174. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  175. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  176. <a-input
  177. v-model="cpaBid"
  178. placeholder="请填写出价金额" style="width: 70%"></a-input>
  179. </a-form-item>
  180. <a-form-item
  181. label="深度转化目标"
  182. v-if="showDeepConversionType"
  183. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  184. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  185. <a-select
  186. v-model="deepConversionType"
  187. showSearch
  188. showArrow
  189. allowClear
  190. optionFilterProp="children"
  191. style="width: 500px"
  192. :filterOption="filterOption"
  193. >
  194. <a-select-option v-for="conversionType in deepConversionTypes"
  195. :key="conversionType.deep_conversion_type"
  196. :value="conversionType.deep_conversion_type">{{conversionType.desc}}
  197. </a-select-option>
  198. </a-select>
  199. </a-form-item>
  200. <a-form-item
  201. label="深度转化目标出价"
  202. v-if="showDeepConversionBid"
  203. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  204. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  205. <a-input
  206. v-model="deepConversionBid"
  207. placeholder="请填写深度转化出价金额" style="width: 70%"></a-input>
  208. </a-form-item>
  209. <a-form-item
  210. label="广告投放位置"
  211. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  212. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  213. <a-radio-group v-model="placementPosition" buttonStyle="solid" @change="changeShowPosition()">
  214. <a-radio-button value='1' :disabled="true">优选广告位</a-radio-button>
  215. <a-radio-button value='2'>按场景选择广告位</a-radio-button>
  216. </a-radio-group>
  217. </a-form-item>
  218. <a-form-item
  219. label="场景广告位"
  220. v-if="showPosition"
  221. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  222. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  223. <a-radio-group v-model="sceneId">
  224. <a-radio-button value='2'>信息流广告</a-radio-button>
  225. <a-radio-button value='3'>视频后贴片广告</a-radio-button>
  226. </a-radio-group>
  227. </a-form-item>
  228. <a-form-item
  229. label="创意制作方式"
  230. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  231. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  232. <a-radio-group v-model="unitType">
  233. <a-radio-button value='4'>自定义</a-radio-button>
  234. <a-radio-button value='2' :disabled="true">程序化创意</a-radio-button>
  235. </a-radio-group>
  236. </a-form-item>
  237. <a-form-item
  238. label="广告组名称"
  239. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  240. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  241. <a-input v-model="unitName" placeholder="请填写广告组名称" style="width: 70%"></a-input>
  242. </a-form-item>
  243. <a-form-item
  244. label="迭代次数"
  245. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  246. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }">
  247. <a-input
  248. v-model="createCount"
  249. placeholder="不小于0,不高于10,仅支持输入自然数" type="number" style="width: 70%"></a-input>
  250. </a-form-item>
  251. <a-form-item
  252. :wrapperCol="{ span: 20 }"
  253. style="text-align: center">
  254. <a-button htmlType="submit" type="primary" :loading="loading">提交</a-button>
  255. <a-button style="margin-left: 8px">保存</a-button>
  256. </a-form-item>
  257. </a-form>
  258. </a-card>
  259. </template>
  260. <script>
  261. import {deleteAction, postAction, getAction} from '@/api/manage'
  262. import moment from "moment"
  263. import {mapGetters} from 'vuex'
  264. import jq from 'jquery'
  265. let dateQuantumRangeConst = '';
  266. export default {
  267. name: 'BaseForm',
  268. data() {
  269. return {
  270. accountId: '',// 账号id
  271. accountList: {},
  272. campaignTemplateId: '',// 广告计划模板id
  273. campaignList: {},
  274. targetPopulation: '',
  275. campaignBudget: 'UNLIMITED',
  276. dayBudget: 0,
  277. showBudgetDaily: false,
  278. speed: '1', // 1 快速投放 2平滑投放
  279. schedulingType: '1',// 1 从今天开始长期投放 2 设置开始和结束日期
  280. showTime: false,
  281. createCount: 0,
  282. time: [],
  283. scheduleTimeType: '1',
  284. showScheduleTime: false,
  285. scheduleTime: '',// 投放时间选择值
  286. showMode: '2', // 1 轮播 2 优选
  287. bidType: '2',
  288. showBid: true,
  289. loading: false,
  290. bid: 0,// bid_type 为 CPC/eCPC 出价
  291. ocpxActionType: '2',// 2行为数 180 激活数
  292. showOcpxActionType: false,
  293. showCpaBid: false,
  294. cpaBid: 0,// bid_type 是 OCPC 时该字段必填
  295. unitName: "_" + moment().format('YYYY-MM-DD_HH:mm'),//广告组名称
  296. activationDisabled: true,
  297. isFormDisabled: true,
  298. placementPosition: '2',
  299. showPosition: true,
  300. sceneId: '2',
  301. deepConversionTypes: [],
  302. deepConversionType: '',
  303. showDeepConversionType: false,
  304. showDeepConversionBid: false,
  305. deepConversionBid: 0,
  306. unitType: '4',
  307. form: this.$form.createForm(this),
  308. url: {
  309. insertTemplateUrl: '/kuaishou/create/createGroups',
  310. userAllocationList: '/ctop/userAllocation/list',
  311. campaignList: '/kuaishou/kuaiShouCampaignTemplate/list',
  312. getDeepConversionUrl: '/kuaishou/kuaiShouConversionTypes/getIsActivate',
  313. }
  314. }
  315. },
  316. methods: {
  317. ...mapGetters(["nickname", "avatar", "userInfo"]),
  318. changeShowPosition() {
  319. if (this.placementPosition == 1) {
  320. this.showPosition = false;
  321. } else {
  322. this.showPosition = true;
  323. }
  324. },
  325. deepConversion() {
  326. if (this.accountId != '') {
  327. let params = {};
  328. params.accountId = this.accountId;
  329. getAction(this.url.getDeepConversionUrl, params).then((res) => {
  330. if (res.success) {
  331. if (res.result.isActivate == 1) {
  332. this.activationDisabled = false;
  333. this.deepConversionTypes = res.result.deepConversionTypes;
  334. } else {
  335. this.activationDisabled = true;
  336. }
  337. if (res.result.isFormSubmit == 1) {
  338. this.isFormDisabled = false;
  339. } else {
  340. this.isFormDisabled = true;
  341. }
  342. } else {
  343. this.activationDisabled = true;
  344. this.isFormDisabled = true;
  345. this.showDeepConversionType = false;
  346. this.showDeepConversionBid = false;
  347. }
  348. });
  349. }
  350. },
  351. showBidType() {
  352. if (this.bidType == '6') {
  353. this.showBid = false;
  354. this.showOcpxActionType = true;
  355. this.showCpaBid = true;
  356. if (this.ocpxActionType == '180' && this.deepConversionTypes.length > 0) {
  357. this.showDeepConversionType = true;
  358. this.showDeepConversionBid = true;
  359. } else {
  360. this.showDeepConversionType = false;
  361. this.showDeepConversionBid = false;
  362. }
  363. } else {
  364. this.showBid = true;
  365. this.showOcpxActionType = false;
  366. this.showCpaBid = false;
  367. }
  368. this.unitName = "_" + moment().format('YYYY-MM-DD HH:mm');
  369. },
  370. showSetScheduleTime() {
  371. if (this.scheduleTimeType == 2) {
  372. this.showScheduleTime = true;
  373. jq(function () {
  374. load_time_table('table_time_selected1', dateQuantumRangeConst);
  375. });
  376. } else {
  377. this.showScheduleTime = false;
  378. }
  379. },
  380. showSetDate() {
  381. if (this.schedulingType == '2') {
  382. this.showTime = true;
  383. } else {
  384. this.showTime = false;
  385. }
  386. },
  387. handleConfirmValue(rule, value, callback) {
  388. if (this.dayBudget == '' || this.dayBudget <= 500 || this.dayBudget >= 100000000) {
  389. callback('请输入正确预算金额')
  390. }
  391. callback()
  392. },
  393. handleConfirmBid(rule, value, callback) {
  394. if (this.bid == 0 || this.bid <= 0.2 || this.bid >= 100) {
  395. callback('不得低于0.2元,不得高于100元')
  396. }
  397. callback()
  398. },
  399. handleConfirmCpaBid(rule, value, callback) {
  400. if (this.ocpxActionType == '2' && (this.cpaBid == 0 || this.cpaBid <= 1 || this.cpaBid >= 3000)) {
  401. callback('金额不得低于1元,不得高于3000元')
  402. }
  403. if (this.ocpxActionType == '180' && (this.cpaBid == 0 || this.cpaBid <= 5 || this.cpaBid >= 3000)) {
  404. callback('金额不得低于5元,不得高于3000元')
  405. }
  406. callback()
  407. },
  408. showBudgetStatusChange() {
  409. if (this.campaignBudget == 'AS_BUDGET') {
  410. this.showBudgetDaily = true;
  411. } else {
  412. this.showBudgetDaily = false;
  413. this.dayBudget = '0';
  414. }
  415. },
  416. handleSubmit(e) {
  417. e.preventDefault()
  418. this.form.validateFields((err, values) => {
  419. if (!err) {
  420. this.loading = true;
  421. console.log('Received values of form: ', values);
  422. console.log('预算金额: ', this.dayBudget);
  423. console.log('投放方式: ', this.speed);
  424. if (this.schedulingType == '1') {
  425. console.log('开始投放时间: ', moment().format('YYYY-MM-DD'));
  426. }
  427. if (this.schedulingType == '2') {
  428. console.log('开始投放时间: ', moment(this.time[0]).format('YYYY-MM-DD'));
  429. console.log('结束投放时间: ', moment(this.time[1]).format('YYYY-MM-DD'));
  430. }
  431. if (this.scheduleTimeType == '2') {
  432. this.scheduleTime = jq("#table_time_selected1_time_num").val();
  433. console.log('投放时间段: ', this.scheduleTime);
  434. }
  435. console.log('出价方式:: ', this.bidType);
  436. if (this.bidType == '2' || this.bidType == '20') {
  437. console.log('出价金额,bid:: ', this.bid);
  438. }
  439. if (this.bidType == '6') {
  440. console.log('优化目标:', this.ocpxActionType);
  441. console.log('出价金额,cpaBid:', this.cpaBid);
  442. }
  443. let params = {};
  444. params.dayBudget = this.dayBudget * 1000;
  445. params.speed = this.speed;
  446. if (this.schedulingType == '1') {
  447. params.beginTime = moment().format('YYYY-MM-DD');
  448. }
  449. if (this.schedulingType == '2') {
  450. params.beginTime = moment(this.time[0]).format('YYYY-MM-DD');
  451. params.endTime = moment(this.time[1]).format('YYYY-MM-DD');
  452. }
  453. if (this.scheduleTimeType == '2') {
  454. this.scheduleTime = jq("#table_time_selected1_time_num").val();
  455. params.scheduleTime = this.scheduleTime;
  456. }
  457. params.bidType = this.bidType;
  458. if (this.bidType == '2' || this.bidType == '20') {
  459. params.bid = this.bid * 1000;
  460. }
  461. if (this.bidType == '6') {
  462. params.ocpxActionType = this.ocpxActionType;
  463. params.cpaBid = this.cpaBid * 1000;
  464. }
  465. params.showModel = this.showMode;
  466. params.unitName = this.unitName;
  467. params.loginId = this.userInfo().id;
  468. params.accountId = this.accountId;
  469. params.campaignTemplateId = this.campaignTemplateId;
  470. params.createCount = this.createCount;
  471. params.sceneId = this.sceneId;
  472. params.unitType = this.unitType;
  473. params.deepConversionType = this.deepConversionType;
  474. params.deepConversionBid = this.deepConversionBid * 1000;
  475. console.log(params)
  476. postAction(this.url.insertTemplateUrl, params).then((res) => {
  477. console.log(res)
  478. if (res.success) {
  479. this.loading = false;
  480. alert("广告组模板创建成功");
  481. } else {
  482. this.loading = false;
  483. alert(res.message);
  484. }
  485. });
  486. }
  487. })
  488. },
  489. onChange(value) {
  490. console.log(value);
  491. },
  492. handleChange(value) {
  493. console.log(`selected ${value}`);
  494. },
  495. handleBlur() {
  496. console.log('blur');
  497. },
  498. handleFocus() {
  499. console.log('focus');
  500. },
  501. filterOption(input, option) {
  502. return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
  503. },
  504. },
  505. created: function () {
  506. let params = {};
  507. params.pageSize = '1000';
  508. params.mediaId = '2';
  509. params.userId = this.userInfo().id;
  510. getAction(this.url.userAllocationList, params).then((res) => {
  511. if (res.success) {
  512. this.accountList = res.result.records
  513. }
  514. });
  515. params = {};
  516. params.loginId = this.userInfo().id;
  517. params.pageSize = '1000';
  518. getAction(this.url.campaignList, params).then((res) => {
  519. if (res.success) {
  520. this.campaignList = res.result.records
  521. console.log("-----" + this.campaignList)
  522. }
  523. });
  524. }
  525. }
  526. var box_id;
  527. var StartTD = null;
  528. var StartIndex = null;
  529. var EndTD = null;
  530. var EndIndex = null;
  531. var Selected = 'Selected';
  532. var Start_x = null;
  533. var Start_y = null;
  534. //点击中表格的小时值
  535. var hour;
  536. //点击选中的星期值
  537. var week;
  538. //1为这个格子在此次鼠标拖拽过程中被选中(不执行选中方法),0为没选中过
  539. var td_state = 0;
  540. //生成星期数组
  541. var num = ['一', '二', '三', '四', '五', '六', '日'];
  542. //生成时间值数组
  543. var arr_hour = get_hour_arr();
  544. //按下鼠标左键拖动选中单元格
  545. function SelectTD(StartIndex, EndIndex, Selected) {
  546. var MinX = null;
  547. var MaxX = null;
  548. var MinY = null;
  549. var MaxY = null;
  550. var coordinate = get_coordinate(StartIndex, EndIndex);
  551. MinX = coordinate[0];
  552. MaxX = coordinate[1];
  553. MinY = coordinate[2];
  554. MaxY = coordinate[3];
  555. for (var i = MinY; i <= MaxY; i++) {
  556. for (var j = MinX; j <= MaxX; j++) {
  557. var SelectTR = jq('#' + box_id + ' table tbody tr ').eq(i);
  558. var td_class = jq("td", SelectTR).eq(j).attr('class');
  559. td_state = jq("td", SelectTR).eq(j).attr("td_state");
  560. //在同一次鼠标按下的过程中,选中过的表格不进行选中或取消操作
  561. if (!td_state) {
  562. if (td_class == Selected) {
  563. jq("td", SelectTR).eq(j).removeClass(Selected);
  564. } else {
  565. //筛选掉标明为星期的表格
  566. jq("td", SelectTR).eq(j).attr("class", Selected);
  567. }
  568. jq("td", SelectTR).eq(j).attr("td_state", '1');
  569. }
  570. }
  571. }
  572. //改变二进制值
  573. get_time_val();
  574. //改变日期显示
  575. convert_date();
  576. }
  577. //点击选中或去掉选中整行、整列
  578. function SelectTD_click(StartIndex, EndIndex, Selected) {
  579. var MinX = null;
  580. var MaxX = null;
  581. var MinY = null;
  582. var MaxY = null;
  583. var Selected_true = 0;
  584. var Selected_false = 0;
  585. var coordinate = get_coordinate(StartIndex, EndIndex);
  586. MinX = coordinate[0];
  587. MaxX = coordinate[1];
  588. MinY = coordinate[2];
  589. MaxY = coordinate[3];
  590. //列出此列当中的表格选中状态
  591. for (var i = MinY; i <= MaxY; i++) {
  592. for (var j = MinX; j <= MaxX; j++) {
  593. var SelectTR = jq('#' + box_id + ' table tbody tr ').eq(i);
  594. var td_class = jq("td", SelectTR).eq(j).attr('class');
  595. if (td_class == Selected) {
  596. //表格里存在已选中的元素
  597. Selected_true = 1;
  598. } else {
  599. //表格里存在未选中的元素
  600. Selected_false = 1;
  601. }
  602. }
  603. }
  604. //执行选中或去掉选中方法
  605. for (var i = MinY; i <= MaxY; i++) {
  606. for (var j = MinX; j <= MaxX; j++) {
  607. var SelectTR = jq('#' + box_id + ' table tbody tr ').eq(i);
  608. var td_class = jq("td", SelectTR).eq(j).attr('class');
  609. //一列当中存在已选中与未选中的表格处理:整列全部选中
  610. if (Selected_true == 1 && Selected_false == 1) {
  611. jq("td", SelectTR).eq(j).attr("class", Selected);
  612. } else if (Selected_false == 1) {
  613. //一列当中只存在未选中的表格处理:整列全部选中
  614. jq("td", SelectTR).eq(j).attr("class", Selected);
  615. } else {
  616. //一列当中只存在已选中的表格处理:整列全部去掉选中
  617. jq("td", SelectTR).eq(j).removeClass(Selected);
  618. }
  619. }
  620. }
  621. //改变二进制值
  622. get_time_val();
  623. //改变日期显示
  624. convert_date();
  625. }
  626. //获取选中范围的开始与结束的坐标
  627. function get_coordinate(StartIndex, EndIndex) {
  628. var MinX = null;
  629. var MaxX = null;
  630. var MinY = null;
  631. var MaxY = null;
  632. if (StartIndex.x < EndIndex.x) {
  633. MinX = StartIndex.x;
  634. MaxX = EndIndex.x;
  635. } else {
  636. MinX = EndIndex.x;
  637. MaxX = StartIndex.x;
  638. }
  639. if (StartIndex.y < EndIndex.y) {
  640. MinY = StartIndex.y;
  641. MaxY = EndIndex.y;
  642. } else {
  643. MinY = EndIndex.y;
  644. MaxY = StartIndex.y;
  645. }
  646. return [MinX, MaxX, MinY, MaxY];
  647. }
  648. //改变二进制值
  649. function get_time_val() {
  650. var time_type = '';
  651. jq('#' + box_id + ' table tbody').find('td').each(function (k) {
  652. var Selected_type = jq(this).attr('class');
  653. var week = jq(this).attr('week');
  654. if (Selected_type == Selected && !week) {
  655. time_type += "1";
  656. } else if (!week) {
  657. time_type += "0";
  658. }
  659. });
  660. jq('#' + box_id + '_time_num').val(time_type);
  661. // convert_date();
  662. }
  663. //二进制数转换日期
  664. function convert_date(external_binary) {
  665. //初始化周数数组
  666. var time_week_arr = [];
  667. if (!external_binary) {
  668. //内部调用,进行选中表格和输出时间操作。
  669. var binary = jq('#' + box_id + '_time_num').val();
  670. } else {
  671. //存在外部参入传入,此函数进行返回时间操作。
  672. var date_html = '';
  673. var binary = external_binary;
  674. }
  675. for (var y = 0; y < 7; y++) {
  676. //初始化小时数组
  677. var time_hour_arr = [];
  678. for (var x = 0; x < 24; x++) {
  679. //获取当前点击元素的位置
  680. if (y == 0) {
  681. var index = x;
  682. } else {
  683. var index = (y * 24) + x;
  684. }
  685. //获取td对应的二进制值
  686. var Selected_val = binary.charAt(index);
  687. if (Selected_val == 1) {
  688. //组装保存进数组里
  689. if (time_hour_arr == []) {
  690. //表格的第一个位置的值
  691. time_hour_arr = arr_hour[x];
  692. } else if (binary.charAt(index - 1) == 1 && binary.charAt(index - 2) == 1) {
  693. //此位置(包含上一行)的前两个都为选中时
  694. if (x == 0 && binary.charAt(index + 1) == 0) {
  695. //选中行里第一个,后一个表格没选中,加逗号
  696. time_hour_arr[time_hour_arr.length] = arr_hour[x] + ', ';
  697. } else if (x == 0 && binary.charAt(index + 1) == 1) {
  698. //选中行里第一个,后一个表格已选中,不加逗号
  699. time_hour_arr[time_hour_arr.length] = arr_hour[x];
  700. } else if (x == 1 && binary.charAt(index - 1) == 0) {
  701. //选中行里第二个,上一个表格没选中,加逗号
  702. time_hour_arr[time_hour_arr.length] = arr_hour[x] + ', ';
  703. } else if (x == 1 && binary.charAt(index - 1) == 1) {
  704. //选中行里第二个,上一个表格已选中,前加-号,后加逗号
  705. time_hour_arr[time_hour_arr.length] = '-' + arr_hour[x] + ', ';
  706. } else {
  707. //选中行里除第一、二的表格以外,前一个表格已经选中,此元素前加- 后加逗号
  708. time_hour_arr[time_hour_arr.length - 1] = '-' + arr_hour[x] + ', ';
  709. }
  710. } else if (binary.charAt(index - 1) == 1 && x > 0) {
  711. //选中的前一个已选中,且此次选中的不是行里第一个,此次选中的元素前加-后加逗号
  712. time_hour_arr[time_hour_arr.length] = '-' + arr_hour[x] + ', ';
  713. } else if (binary.charAt(index + 1) != 1 || x == 23) {
  714. //选中的后一个没选中,或者此次选中的是行里最后一个,此次选中的元素加逗号
  715. time_hour_arr[time_hour_arr.length] = arr_hour[x] + ', ';
  716. } else {
  717. //选中的后一已选中,此次选中的元素不加逗号
  718. time_hour_arr[time_hour_arr.length] = arr_hour[x];
  719. }
  720. }
  721. }
  722. time_week_arr[y] = time_hour_arr;
  723. }
  724. // console.info(box_id);
  725. if (!external_binary) {
  726. jq('#' + box_id + '_time_seled').html('');
  727. }
  728. //再次组装并输出数组
  729. var time_html = [];
  730. for (var y = 0; y < 7; y++) {
  731. for (var x = 0; x < time_week_arr[y].length; x++) {
  732. if (!time_html[y]) {
  733. time_html[y] = time_week_arr[y][x];
  734. } else {
  735. time_html[y] += time_week_arr[y][x];
  736. }
  737. }
  738. if (time_html[y]) {
  739. time_html[y] = time_html[y].substring(0, time_html[y].length - 2);
  740. if (!external_binary) {
  741. jq('#' + box_id + '_time_seled').append('<div>星期' + num [y] + ' (' + time_html[y] + ')' + '</div>');
  742. } else {
  743. date_html += '星期' + num [y] + ' (' + time_html[y] + ')' + ', ';
  744. }
  745. }
  746. }
  747. if (external_binary) {
  748. return date_html;
  749. }
  750. // console.info(time_html);
  751. }
  752. //生成时间值数组
  753. function get_hour_arr() {
  754. var arr_hour = [];
  755. var oDate = new Date("2016/07/01 00:00:00"); //实例一个时间对象;
  756. var oDate_hour = oDate.getHours();
  757. var oDate_minute = oDate.getMinutes();
  758. for (var i = 0; i < 24; i++) {
  759. if (oDate_minute < 10) {
  760. var oDate_minute = "0" + oDate_minute;
  761. }
  762. if (i >= 1) {
  763. oDate.setMinutes(oDate.getMinutes() + 60);
  764. oDate_hour = oDate.getHours();
  765. oDate_minute = oDate.getMinutes();
  766. if (oDate_minute < 10) {
  767. var oDate_minute = "0" + oDate_minute;
  768. }
  769. }
  770. arr_hour[i] = oDate_hour + ':' + oDate_minute;
  771. }
  772. return arr_hour;
  773. }
  774. //更新操作
  775. function renewal(id) {
  776. if (id) {
  777. box_id = id;
  778. }
  779. //解绑鼠标移动监听事件
  780. jq('#' + box_id + ' table tbody tr td').unbind("mouseover");
  781. //初始化表格的在此次选中状态
  782. jq('#' + box_id + ' table tbody tr td').attr("td_state", '');
  783. //改变二进制值
  784. get_time_val();
  785. //改变日期显示
  786. convert_date();
  787. }
  788. //二进制数赋值选中表格
  789. function binary_selected() {
  790. var default_time_val = jq('#' + box_id + ' .default_time_val').val();
  791. if (default_time_val) {
  792. for (var i = 0; i < 168; i++) {
  793. var td_selected = default_time_val.charAt(i);
  794. if (td_selected != 0) {
  795. jq('#' + box_id + ' table tbody tr td').eq(i).attr('class', 'Selected');
  796. //更新操作,显示文字形日期
  797. renewal();
  798. }
  799. }
  800. }
  801. }
  802. //实例化程序
  803. function load_time_table(id, value) {
  804. //包住table的元素id
  805. box_id = id;
  806. var html;
  807. html = '<input type="hidden" class="default_time_val" value="' + value + '"/>';
  808. html += '<table cellspacing="0" cellpadding="0" border="0" class="plug-timer-grid" onselectstart="return false" onselect="document.selection.empty()">';
  809. html += '<thead>';
  810. html += '<tr>';
  811. html += '<th></th>';
  812. html += '<th colSpan="12">上午</th>';
  813. html += '<th colSpan="12">下午</th>';
  814. html += '</tr>';
  815. html += '<tr class="hour">';
  816. html += '<th></th>';
  817. html += '</tr>';
  818. html += '</thead>';
  819. html += '<tbody></tbody>';
  820. html += '</table>';
  821. html += '<input class="focus" type="hidden" style="opacity: 0;">';
  822. html += '<div id="' + box_id + '_time_seled" style="line-height: 15px;font-size:10px;"></div>';
  823. html += '<input type="hidden" id="' + box_id + '_time_num" name="time" caption="每日投放时段" switchname="selectTime" value="' + value + '">';
  824. jq('#' + box_id).html('');
  825. jq('#' + box_id).append(html);
  826. var html_tbody_td = '';
  827. var html_thead_td = '';
  828. //创建表格
  829. for (var i = 0; i < 7; i++) {
  830. var week = i + 1;
  831. html_tbody_td += '<tr>';
  832. for (var j = 0; j < 25; j++) {
  833. if (j == 0) {
  834. html_tbody_td += '<th week="' + week + '">星期' + num[i] + '</th>';
  835. } else {
  836. html_tbody_td += '<td>' + '</td>';
  837. }
  838. }
  839. html_tbody_td += '</tr>';
  840. }
  841. //创建表格小时栏目
  842. for (var i = 0; i <= 23; i++) {
  843. html_thead_td += '<td hour="' + i + '">' + i + '</td>';
  844. }
  845. jq('#' + box_id + ' table thead .hour').append(html_thead_td);
  846. jq('#' + box_id + ' table tbody').html(html_tbody_td);
  847. //检查是否有赋有二进制值,如有,将选中相应的表格
  848. binary_selected();
  849. //控制器,控制当前在哪个表格进行操作
  850. jq('.plug-timer-grid').hover(function (e) {
  851. if (1 != e.which) { //判断是否为左击
  852. var id = jq(this).parent().attr('id');
  853. box_id = id;
  854. }
  855. });
  856. //清除所有选中项
  857. jq('.clear').click(function () {
  858. jq(this).parent().find('td').removeClass(Selected);
  859. var id = jq(this).parent().attr('id');
  860. renewal(id);
  861. });
  862. //点击小时选中或去掉整列处理块
  863. jq('#' + box_id + ' table thead tr td').click(function () {
  864. hour = jq(this).attr('hour');
  865. if (hour >= 0) {
  866. var rows = jq('#' + box_id + ' table tbody tr').length;
  867. Start_x = (jq(this).index()) * 2 - 1;
  868. Start_y = 0;
  869. StartIndex = {x: Start_x, y: Start_y};
  870. EndTD = jq(this);
  871. var x = (jq(this).index()) * 2 - 2;
  872. var y = rows - 1; //为了配合for计算公式-1
  873. EndIndex = {x: x, y: y};
  874. //改变第一次按下鼠标时候的改变选中状态
  875. SelectTD_click(StartIndex, EndIndex, Selected);
  876. }
  877. });
  878. //点击星期选中或去掉整行处理块
  879. jq('#' + box_id + ' table tbody tr th').click(function () {
  880. var week = jq(this).attr('week');
  881. if (week >= 0) {
  882. var line = jq('#' + box_id + ' table tbody tr td').length / jq('#' + box_id + ' table tbody tr').length;
  883. Start_x = 0;
  884. Start_y = jq(this).parent().index();
  885. StartIndex = {x: Start_x, y: Start_y};
  886. EndTD = jq(this);
  887. var y = jq(this).parent().index();
  888. var x = line - 1; //为了配合for计算公式-1
  889. EndIndex = {x: x, y: y};
  890. //改变第一次按下鼠标时候的改变选中状态
  891. SelectTD_click(StartIndex, EndIndex, Selected);
  892. }
  893. });
  894. //监听鼠标按下事件(鼠标按下左键拖动选中处理块)
  895. jq('#' + box_id + ' table tbody tr td').unbind("mousedown").bind("mousedown", function () {
  896. //记录刚开始点击的元素位置
  897. Start_x = jq(this).index() - 1;
  898. Start_y = jq(this).parent().index();
  899. StartIndex = {x: Start_x, y: Start_y};
  900. EndTD = jq(this);
  901. var x = jq(this).index() - 1;
  902. var y = jq(this).parent().index();
  903. EndIndex = {x: x, y: y};
  904. //改变第一次按下鼠标时候的改变选中状态
  905. SelectTD(StartIndex, EndIndex, Selected);
  906. StartTD = jq(this);
  907. StartIndex = {x: Start_x, y: Start_y};
  908. //监听鼠标移动事件,实现改变后续鼠标拖拽时候的表格选中状态
  909. jq('#' + box_id + ' table tbody tr td').mouseover(function (e) {
  910. EndTD = jq(this);
  911. var x = jq(this).index() - 1;
  912. var y = jq(this).parent().index();
  913. EndIndex = {x: x, y: y};
  914. if (1 != e.which) { //判断是否为左击
  915. jq('#' + box_id + ' table tbody tr td').unbind("mouseover");
  916. }
  917. //去除停留在td上的光标
  918. jq('#' + box_id + ' .focus').focus();
  919. SelectTD(StartIndex, EndIndex, Selected);
  920. });
  921. //放开鼠标左键时,初始化相关参数和解绑相关监听
  922. jq('html').unbind("mouseup").bind("mouseup", function () {
  923. renewal();
  924. });
  925. });
  926. }
  927. /*外部调用接口*/
  928. //解绑鼠标松开监听事件
  929. function unbundle_mouseover() {
  930. jq('html').unbind("mouseup");
  931. }
  932. /*二进制获取转换后的时间*/
  933. function get_time_html(binary) {
  934. return convert_date(binary);
  935. }
  936. jq(function () {
  937. load_time_table('table_time_selected1', this.dateQuantumRange);
  938. });
  939. </script>
  940. <style type="text/css">
  941. .plug-timer-grid {
  942. width: 100%;
  943. }
  944. .plug-timer-grid td, .plug-timer-grid th {
  945. border: 1px solid #97B4D1;
  946. text-align: center; /*cursor:pointer;*/
  947. font-size: 10px;
  948. line-height: 10px;
  949. }
  950. .Selected {
  951. background-color: rgb(102, 162, 243);
  952. opacity: 0.5;
  953. }
  954. .plug-timer-grid {
  955. border-collapse: collapse;
  956. z-index: 4;
  957. }
  958. .plug-timer-grid thead tr {
  959. display: table-row;
  960. vertical-align: inherit;
  961. border-color: inherit;
  962. }
  963. table td {
  964. height: 20px;
  965. max-width: 5px;
  966. border: 1px solid #dfe6ec;
  967. font-size: 12px;
  968. text-align: center;
  969. vertical-align: middle;
  970. overflow: hidden;
  971. transition: background .5s;
  972. -webkit-transition: background .5s;
  973. }
  974. .plug-timer-grid tbody th {
  975. width: 4%;
  976. }
  977. .plug-timer-grid tbody tr td {
  978. width: 2%;
  979. }
  980. /*.clear{*/
  981. /* margin:20px 0px 20px 0px;*/
  982. /*}*/
  983. </style>