publish.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. <template>
  2. <view>
  3. <!-- 顶部导航 -->
  4. <fa-navbar title="发布文章"></fa-navbar>
  5. <view class="u-p-30" v-if="showForm">
  6. <u-form :model="form" :rules="rules" ref="uForm" :errorType="errorType">
  7. <!-- 系统字段 -->
  8. <u-form-item :label-position="labelPosition" label="副栏目:" label-width="130" v-if="contributefields.indexOf('channel_ids') != -1">
  9. <fa-selects
  10. :fa-list="secondList"
  11. title="请选择副栏目"
  12. checkeType="selects"
  13. :showValue="archives && archives.channel_ids"
  14. v-model="form.channel_ids"
  15. ></fa-selects>
  16. </u-form-item>
  17. <!-- -->
  18. <u-form-item :label-position="labelPosition" label="标题:" prop="title" :required="rules.title && rules.title.length > 0" label-width="130">
  19. <u-input :border="border" placeholder="请输入标题" v-model="form.title" type="text"></u-input>
  20. </u-form-item>
  21. <!-- -->
  22. <u-form-item :label-position="labelPosition" label="略缩图:" label-width="130" v-if="contributefields.indexOf('image') != -1">
  23. <fa-upload-image v-model="form.image" :file-list="imageList.image || []"></fa-upload-image>
  24. </u-form-item>
  25. <!-- -->
  26. <u-form-item :label-position="labelPosition" label="组图:" label-width="130" v-if="contributefields.indexOf('images') != -1">
  27. <fa-upload-image v-model="form.images" imgType="many" :file-list="imageList.images || []"></fa-upload-image>
  28. </u-form-item>
  29. <!-- -->
  30. <u-form-item :label-position="labelPosition" label="标签:" label-width="130" v-if="contributefields.indexOf('tags') != -1">
  31. <fa-tags v-model="form.tags" :tagList="archives && archives.tags"></fa-tags>
  32. </u-form-item>
  33. <!-- -->
  34. <!-- #ifdef MP-WEIXIN || H5 || APP-PLUS -->
  35. <u-form-item :label-position="labelPosition" label-width="130" label="内容:" v-if="contributefields.indexOf('content') != -1">
  36. <fa-editor v-model="form.content" :html="field_values.content"></fa-editor>
  37. </u-form-item>
  38. <!-- #endif -->
  39. <!-- -->
  40. <u-form-item :label-position="labelPosition" label-width="130" label="关键字:" v-if="contributefields.indexOf('keywords') != -1">
  41. <u-input type="text" :border="border" placeholder="请填写关键字" v-model="form.keywords"></u-input>
  42. </u-form-item>
  43. <!-- -->
  44. <u-form-item :label-position="labelPosition" label-width="130" label="描述:" v-if="contributefields.indexOf('description') != -1">
  45. <u-input type="textarea" :border="border" placeholder="请填写描述" v-model="form.description"></u-input>
  46. </u-form-item>
  47. <!-- 自定义字段 -->
  48. <block v-for="(item, index) in fields" :key="index">
  49. <!-- 字符 -->
  50. <u-form-item
  51. :label-position="labelPosition"
  52. label-width="130"
  53. :prop="item.name"
  54. :label="item.title"
  55. :required="rules[item.name] && rules[item.name].length > 0"
  56. v-if="item.type == 'string'"
  57. >
  58. <u-input type="text" :border="border" :placeholder="'请填写' + item.title" v-model="form[item.name]"></u-input>
  59. </u-form-item>
  60. <!-- 文本 -->
  61. <u-form-item
  62. :label-position="labelPosition"
  63. label-width="130"
  64. :prop="item.name"
  65. :label="item.title"
  66. :required="rules[item.name] && rules[item.name].length > 0"
  67. v-if="item.type == 'text'"
  68. >
  69. <u-input type="textarea" :border="border" :placeholder="'请填写' + item.title" v-model="form[item.name]"></u-input>
  70. </u-form-item>
  71. <!-- 编辑器 -->
  72. <!-- #ifdef MP-WEIXIN || H5 || APP-PLUS -->
  73. <u-form-item
  74. :label-position="labelPosition"
  75. label-width="130"
  76. :prop="item.name"
  77. :label="item.title"
  78. :required="rules[item.name] && rules[item.name].length > 0"
  79. v-if="item.type == 'editor'"
  80. >
  81. <fa-editor v-model="form[item.name]" :html="field_values[item.name]"></fa-editor>
  82. </u-form-item>
  83. <!-- #endif -->
  84. <!-- 数组 -->
  85. <u-form-item
  86. :label-position="labelPosition"
  87. label-width="130"
  88. :prop="item.name"
  89. :label="item.title"
  90. :required="rules[item.name] && rules[item.name].length > 0"
  91. v-if="item.type == 'array' && item.name != 'downloadurl'"
  92. >
  93. <fa-array :faKey="item.setting.key" :faVal="item.setting.value" v-model="form[item.name]" :showValue="field_values[item.name]"></fa-array>
  94. </u-form-item>
  95. <!-- 数组(下载) -->
  96. <u-form-item
  97. :label-position="labelPosition"
  98. label-width="130"
  99. :prop="item.name"
  100. :label="item.title"
  101. :required="rules[item.name] && rules[item.name].length > 0"
  102. v-if="item.type == 'array' && item.name == 'downloadurl'"
  103. >
  104. <fa-array-download v-model="form[item.name]" :showValue="field_values[item.name]" :contentList="item.content_list"></fa-array-download>
  105. </u-form-item>
  106. <!-- 日期 -->
  107. <u-form-item
  108. :label-position="labelPosition"
  109. label-width="130"
  110. :prop="item.name"
  111. :label="item.title"
  112. :required="rules[item.name] && rules[item.name].length > 0"
  113. v-if="item.type == 'date'"
  114. >
  115. <u-input
  116. :border="border"
  117. type="select"
  118. :select-open="showPicker && mode == 'date'"
  119. v-model="form[item.name]"
  120. :placeholder="'请选择' + item.title"
  121. @click="selectPicker('date', item.name)"
  122. ></u-input>
  123. </u-form-item>
  124. <!-- 时间 -->
  125. <u-form-item
  126. :label-position="labelPosition"
  127. label-width="130"
  128. :prop="item.name"
  129. :label="item.title"
  130. :required="rules[item.name] && rules[item.name].length > 0"
  131. v-if="item.type == 'time'"
  132. >
  133. <u-input
  134. :border="border"
  135. type="select"
  136. :select-open="showPicker && mode == 'time'"
  137. v-model="form[item.name]"
  138. :placeholder="'请选择' + item.title"
  139. @click="selectPicker('time', item.name)"
  140. ></u-input>
  141. </u-form-item>
  142. <!-- 日期时间 -->
  143. <u-form-item
  144. :label-position="labelPosition"
  145. label-width="130"
  146. :prop="item.name"
  147. :label="item.title"
  148. :required="rules[item.name] && rules[item.name].length > 0"
  149. v-if="item.type == 'datetime'"
  150. >
  151. <u-input
  152. :border="border"
  153. type="select"
  154. :select-open="showPicker && mode == 'datetime'"
  155. v-model="form[item.name]"
  156. :placeholder="'请选择' + item.title"
  157. @click="selectPicker('datetime', item.name)"
  158. ></u-input>
  159. </u-form-item>
  160. <!-- 日期区间 -->
  161. <u-form-item
  162. :label-position="labelPosition"
  163. label-width="130"
  164. :prop="item.name"
  165. :label="item.title"
  166. :required="rules[item.name] && rules[item.name].length > 0"
  167. v-if="item.type == 'datetimerange'"
  168. >
  169. <u-input
  170. :border="border"
  171. type="select"
  172. :select-open="calendarShow"
  173. v-model="form[item.name]"
  174. :placeholder="'请选择' + item.title"
  175. @click="
  176. calendarShow = true;
  177. time_field = item.name;
  178. "
  179. ></u-input>
  180. </u-form-item>
  181. <!-- 数字 -->
  182. <u-form-item
  183. :label-position="labelPosition"
  184. label-width="130"
  185. :prop="item.name"
  186. :label="item.title"
  187. :required="rules[item.name] && rules[item.name].length > 0"
  188. v-if="item.type == 'number'"
  189. >
  190. <u-input type="number" :border="border" :placeholder="'请填写' + item.title" v-model="form[item.name]"></u-input>
  191. </u-form-item>
  192. <!-- 多选框 -->
  193. <u-form-item
  194. :label-position="labelPosition"
  195. label-width="130"
  196. :prop="item.name"
  197. :label="item.title"
  198. :required="rules[item.name] && rules[item.name].length > 0"
  199. v-if="item.type == 'checkbox'"
  200. >
  201. <fa-check-radio
  202. :faList="item.content_list"
  203. v-model="form[item.name]"
  204. :checkValue="field_values[item.name] || item.defaultvalue"
  205. ></fa-check-radio>
  206. </u-form-item>
  207. <!-- 单选框 -->
  208. <u-form-item
  209. :label-position="labelPosition"
  210. label-width="130"
  211. :prop="item.name"
  212. :label="item.title"
  213. :required="rules[item.name] && rules[item.name].length > 0"
  214. v-if="item.type == 'radio'"
  215. >
  216. <fa-check-radio
  217. :faList="item.content_list"
  218. type="radio"
  219. v-model="form[item.name]"
  220. :checkValue="field_values[item.name] || item.defaultvalue"
  221. ></fa-check-radio>
  222. </u-form-item>
  223. <!-- 列表单选 -->
  224. <u-form-item
  225. :label-position="labelPosition"
  226. label-width="130"
  227. :prop="item.name"
  228. :label="item.title"
  229. :required="rules[item.name] && rules[item.name].length > 0"
  230. v-if="item.type == 'select'"
  231. >
  232. <fa-selects
  233. :fa-list="item.content_list"
  234. :title="item.title"
  235. :checkeType="item.type"
  236. :showValue="field_values[item.name] || item.defaultvalue"
  237. v-model="form[item.name]"
  238. ></fa-selects>
  239. </u-form-item>
  240. <!-- 列表多选 -->
  241. <u-form-item
  242. :label-position="labelPosition"
  243. label-width="130"
  244. :prop="item.name"
  245. :label="item.title"
  246. :required="rules[item.name] && rules[item.name].length > 0"
  247. v-if="item.type == 'selects'"
  248. >
  249. <fa-selects
  250. :fa-list="item.content_list"
  251. :title="item.title"
  252. :checkeType="item.type"
  253. :showValue="field_values[item.name] || item.defaultvalue"
  254. v-model="form[item.name]"
  255. ></fa-selects>
  256. </u-form-item>
  257. <!-- 单图 -->
  258. <u-form-item
  259. :label-position="labelPosition"
  260. label-width="130"
  261. :prop="item.name"
  262. :label="item.title"
  263. :required="rules[item.name] && rules[item.name].length > 0"
  264. v-if="item.type == 'image'"
  265. >
  266. <fa-upload-image v-model="form[item.name]" :file-list="imageList[item.name] || []"></fa-upload-image>
  267. </u-form-item>
  268. <!-- 多图 -->
  269. <u-form-item
  270. :label-position="labelPosition"
  271. label-width="130"
  272. :prop="item.name"
  273. :label="item.title"
  274. :required="rules[item.name] && rules[item.name].length > 0"
  275. v-if="item.type == 'images'"
  276. >
  277. <fa-upload-image v-model="form[item.name]" imgType="many" :file-list="imageList[item.name] || []"></fa-upload-image>
  278. </u-form-item>
  279. <!-- #ifdef APP-PLUS || H5 || MP-WEIXIN -->
  280. <!-- 单文件 -->
  281. <u-form-item
  282. :label-position="labelPosition"
  283. label-width="130"
  284. :prop="item.name"
  285. :label="item.title"
  286. :required="rules[item.name] && rules[item.name].length > 0"
  287. v-if="item.type == 'file'"
  288. >
  289. <fa-upload-file v-model="form[item.name]" :isDom="true" :showValue="imageList[item.name] || []"></fa-upload-file>
  290. </u-form-item>
  291. <!-- 多文件 -->
  292. <u-form-item
  293. :label-position="labelPosition"
  294. label-width="130"
  295. :prop="item.name"
  296. :label="item.title"
  297. :required="rules[item.name] && rules[item.name].length > 0"
  298. v-if="item.type == 'files'"
  299. >
  300. <fa-upload-file v-model="form[item.name]" fileType="many" :isDom="true" :showValue="imageList[item.name] || []"></fa-upload-file>
  301. </u-form-item>
  302. <!-- #endif -->
  303. <!-- 开关 -->
  304. <u-form-item
  305. :label-position="labelPosition"
  306. label-width="130"
  307. :prop="item.name"
  308. :label="item.title"
  309. :required="rules[item.name] && rules[item.name].length > 0"
  310. v-if="item.type == 'switch'"
  311. >
  312. <fa-switch v-model="form[item.name]" :defvalue="field_values[item.name] || 0"></fa-switch>
  313. </u-form-item>
  314. <!-- 关联城市 -->
  315. <u-form-item
  316. :label-position="labelPosition"
  317. label-width="130"
  318. :prop="item.name"
  319. :label="item.title"
  320. :required="rules[item.name] && rules[item.name].length > 0"
  321. v-if="item.type == 'city'"
  322. >
  323. <u-input
  324. :border="border"
  325. type="select"
  326. :select-open="cityShow"
  327. v-model="form[item.name]"
  328. :placeholder="'请选择' + item.title"
  329. @click="
  330. cityShow = true;
  331. city_field = item.name;
  332. "
  333. ></u-input>
  334. </u-form-item>
  335. <!-- 关联单选 -->
  336. <u-form-item
  337. :label-position="labelPosition"
  338. label-width="130"
  339. :prop="item.name"
  340. :label="item.title"
  341. :required="rules[item.name] && rules[item.name].length > 0"
  342. v-if="item.type == 'selectpage'"
  343. >
  344. <fa-selectpages
  345. :fa-id="item.id"
  346. :title="item.title"
  347. :checkeType="item.type"
  348. :showField="item.setting.field"
  349. :keyField="item.setting.primarykey"
  350. :showValue="(form[item.name] ? form[item.name] : field_values[item.name]) || item.defaultvalue"
  351. v-model="form[item.name]"
  352. ></fa-selectpages>
  353. </u-form-item>
  354. <!-- 关联多选 -->
  355. <u-form-item
  356. :label-position="labelPosition"
  357. label-width="130"
  358. :prop="item.name"
  359. :label="item.title"
  360. :required="rules[item.name] && rules[item.name].length > 0"
  361. v-if="item.type == 'selectpages'"
  362. >
  363. <fa-selectpages
  364. :fa-id="item.id"
  365. :title="item.title"
  366. :checkeType="item.type"
  367. :showField="item.setting.field"
  368. :keyField="item.setting.primarykey"
  369. :showValue="(form[item.name] ? form[item.name] : field_values[item.name]) || item.defaultvalue"
  370. v-model="form[item.name]"
  371. ></fa-selectpages>
  372. </u-form-item>
  373. </block>
  374. </u-form>
  375. <view class="u-p-30">
  376. <u-button type="primary" hover-class="none" :custom-style="{ backgroundColor: theme.bgColor, color: theme.color }" shape="circle" @click="submit">
  377. 提交
  378. </u-button>
  379. </view>
  380. </view>
  381. <u-picker v-model="showPicker" mode="time" :params="params" @confirm="pickerResult"></u-picker>
  382. <u-calendar v-model="calendarShow" mode="range" @change="calendarResult" max-date="3000-01-01"></u-calendar>
  383. <!-- 城市 -->
  384. <fa-citys v-model="cityShow" @city-change="cityResult"></fa-citys>
  385. <!-- 底部导航 -->
  386. <fa-tabbar></fa-tabbar>
  387. </view>
  388. </template>
  389. <script>
  390. import { formRule, tools } from '@/common/fa.mixin.js';
  391. export default {
  392. mixins: [formRule, tools],
  393. onLoad(e) {
  394. let query = this.$Route.query || e || {};
  395. this.archives_id = query.archives_id || 0;
  396. this.getChannelFields();
  397. },
  398. data() {
  399. return {
  400. labelPosition: 'top',
  401. border: false,
  402. errorType: ['message'],
  403. showForm: false,
  404. contributefields: [], //系统可投稿字段
  405. fields: [], //自定义可投稿字段
  406. // 系统表单字段
  407. form: {},
  408. rules: {},
  409. secondList: [],
  410. calendarShow: false,
  411. showPicker: false,
  412. mode: '',
  413. time_field: '',
  414. params: {},
  415. cityShow: false,
  416. city_field: '',
  417. archives_id: '',
  418. field_values: {}, //附表的数据
  419. archives: {}, //主表的数据
  420. imageList: {} //图片展示
  421. };
  422. },
  423. methods: {
  424. //获取字段
  425. getChannelFields() {
  426. this.$api.getChannelFields({ channel_id: this.vuex_channel_id, archives_id: this.archives_id }).then(res => {
  427. if (res.code) {
  428. this.secondList = res.data.secondList;
  429. this.field_values = res.data.values;
  430. this.archives = res.data.archives;
  431. let sys = res.data.contributefields;
  432. let custom = res.data.fields;
  433. //渲染系统字段
  434. let form_sys = {
  435. channel_ids: '',
  436. title: '',
  437. channel_id: this.vuex_channel_id,
  438. id: this.archives_id
  439. };
  440. for (let i in sys) {
  441. form_sys[sys[i]] = '';
  442. }
  443. //渲染自定义字段
  444. let custom_form = {};
  445. let rules = {
  446. title: [
  447. {
  448. required: true,
  449. message: '请输入标题',
  450. // 可以单个或者同时写两个触发验证方式
  451. trigger: ['change', 'blur']
  452. }
  453. ]
  454. };
  455. let number_arr = [];
  456. custom.map(item => {
  457. // console.log(item)
  458. custom_form[item.name] = item.defaultvalue || '';
  459. if (item.type == 'number') {
  460. number_arr.push(item.name);
  461. }
  462. //追加自定义表单验证
  463. rules[item.name] = this.getRules(item);
  464. });
  465. this.form = Object.assign(form_sys, custom_form);
  466. this.rules = rules;
  467. //赋值
  468. this.contributefields = sys;
  469. this.fields = custom;
  470. //渲染表单数据
  471. this.setFormData(res.data.archives, res.data.values, number_arr);
  472. this.showForm = true;
  473. //设置表单验证规则
  474. this.$nextTick(() => {
  475. this.$refs.uForm.setRules(this.rules);
  476. });
  477. }
  478. });
  479. },
  480. //编辑渲染数据
  481. setFormData(archives, values, number_arr) {
  482. //给from值
  483. for (let i in this.form) {
  484. if (values && values[i]) {
  485. if (number_arr.indexOf(i) != -1) {
  486. this.form[i] = values[i] + '';
  487. } else {
  488. this.form[i] = values[i];
  489. }
  490. }
  491. if (archives && archives[i]) {
  492. this.form[i] = archives[i];
  493. }
  494. }
  495. //系统图片赋值
  496. if (archives && archives.image) {
  497. this.imageList.image = [
  498. {
  499. url: this.cdnurl(archives.image)
  500. }
  501. ];
  502. }
  503. if (archives && archives.images) {
  504. let images = archives.images.split(',');
  505. let urls = [];
  506. images.forEach(item => {
  507. urls.push({
  508. url: this.cdnurl(item)
  509. });
  510. });
  511. this.imageList.images = urls;
  512. }
  513. //自定义图片字段赋值
  514. this.fields.forEach(item => {
  515. if (item.type == 'image' && values[item.name]) {
  516. this.imageList[item.name] = [
  517. {
  518. url: this.cdnurl(values[item.name])
  519. }
  520. ];
  521. }
  522. if (item.type == 'images' && values[item.name]) {
  523. let images = values[item.name].split(',');
  524. let urls = [];
  525. images.forEach(item => {
  526. urls.push({
  527. url: this.cdnurl(item)
  528. });
  529. });
  530. this.imageList[item.name] = urls;
  531. }
  532. if (item.type == 'file') {
  533. this.imageList[item.name] = values[item.name] ? [values[item.name]] : [];
  534. }
  535. if (item.type == 'files') {
  536. this.imageList[item.name] = values[item.name] ? values[item.name].split(',') : [];
  537. }
  538. });
  539. },
  540. //时间显示
  541. selectPicker(mode, field) {
  542. this.mode = mode;
  543. this.time_field = field;
  544. switch (mode) {
  545. case 'date':
  546. this.params = {
  547. year: true,
  548. month: true,
  549. day: true,
  550. hour: false,
  551. minute: false,
  552. second: false
  553. };
  554. break;
  555. case 'time':
  556. this.params = {
  557. year: false,
  558. month: false,
  559. day: false,
  560. hour: true,
  561. minute: true,
  562. second: true
  563. };
  564. break;
  565. case 'datetime':
  566. this.params = {
  567. year: true,
  568. month: true,
  569. day: true,
  570. hour: true,
  571. minute: true,
  572. second: true
  573. };
  574. break;
  575. }
  576. this.showPicker = true;
  577. },
  578. //时间的选择结果
  579. pickerResult(e) {
  580. switch (this.mode) {
  581. case 'date':
  582. this.$set(this.form, this.time_field, e.year + '-' + e.month + '-' + e.day);
  583. break;
  584. case 'time':
  585. this.$set(this.form, this.time_field, e.hour + ':' + e.minute + ':' + e.second);
  586. break;
  587. case 'datetime':
  588. this.$set(this.form, this.time_field, e.year + '-' + e.month + '-' + e.day + ' ' + e.hour + ':' + e.minute + ':' + e.second);
  589. break;
  590. }
  591. },
  592. //时间范围选择的结果
  593. calendarResult(e) {
  594. this.$set(this.form, this.time_field, e.startDate + ' 00:00:00 - ' + e.endDate + ' 23:59:59');
  595. },
  596. //城市选择
  597. cityResult(e) {
  598. this.$set(this.form, this.city_field, e.province.label + '/' + e.city.label + '/' + e.area.label);
  599. },
  600. //提交
  601. submit: async function() {
  602. console.log('验证开始', this.form);
  603. //校验
  604. this.$refs.uForm.validate(valid => {
  605. if (valid) {
  606. console.log('验证通过', this.form);
  607. this.$api.archivesPost(this.form).then(res => {
  608. this.$u.toast(res.msg);
  609. if (res.code) {
  610. setTimeout(() => {
  611. this.$Router.replace('/pages/publish/myarticle');
  612. }, 1500);
  613. }
  614. });
  615. } else {
  616. console.log('验证失败', this.form);
  617. }
  618. });
  619. }
  620. }
  621. };
  622. </script>
  623. <style lang="scss">
  624. page {
  625. background-color: #ffffff;
  626. }
  627. </style>