list.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. <template>
  2. <div style="padding-top: 10px;">
  3. <i-page-header :title="pageTitle"></i-page-header>
  4. <Card :bordered="false" dis-hover class="ivu-mt">
  5. <!-- <Form ref="orderData" :model="orderData">
  6. <Row :gutter="24" type="flex">
  7. <Col>
  8. <FormItem label="UID:" label-for="uid">
  9. <Input placeholder="用户UID" v-model="orderData.uid"/>
  10. </FormItem>
  11. </Col>
  12. <Col>
  13. <FormItem label="绑定手机:" label-for="mobile">
  14. <Input placeholder="绑定手机号码" v-model="orderData.mobile"/>
  15. </FormItem>
  16. </Col>
  17. <Col>
  18. <FormItem label="购买时间:">
  19. <DatePicker v-model="orderData.time" format="yyyy/MM/dd HH:mm:ss" type="datetimerange" placement="bottom-start" placeholder="自定义时间" style="width: 300px;" class="mr20" :options="options"></DatePicker>
  20. </FormItem>
  21. </Col>
  22. <Col>
  23. <Button label="default" type="primary" icon="ios-search" class="mr15" style="margin-top: 32px;" @click="orderSearch()">搜索</Button>
  24. </Col>
  25. </Row>
  26. </Form> -->
  27. <Col>
  28. <Button type="primary" class="export" icon="ios-share-outline" @click="sendOpen">添加商品</Button>
  29. </Col>
  30. <Table :columns="columns" :data="orderList" ref="table" :loading="loading" highlight-row no-data-text="暂无数据"
  31. no-filtered-data-text="暂无筛选结果" class="orderData mt25">
  32. <template slot-scope="{ row, index }" slot="order_id">
  33. <span v-text="row.order_id" style="display: block;"></span>
  34. </template>
  35. <template slot-scope="{ row, index }" slot="uid">
  36. <div>{{row.nickname || '微信用户'}}[UID:{{row.uid}}]</div>
  37. <div>{{row.mobile || '未绑定手机号'}}</div>
  38. </template>
  39. <template slot-scope="{ row, index }" slot="imgs">
  40. <div v-if="row.imgs.length>0" style="display: flex;">
  41. <img v-for="item in row.imgs" v-lazy="item" :src="item" v-image-preview
  42. style="width: 60px;cursor: pointer" />
  43. </div>
  44. </template>
  45. <template slot-scope="{ row, index }" slot="handle">
  46. <div><el-button plain size="mini" @click="">查看评论</el-button></div>
  47. <br />
  48. <div><el-button plain size="mini" @click="">删除</el-button></div>
  49. </template>
  50. </Table>
  51. <div class="acea-row row-right page">
  52. <Page :total="page.count" show-elevator show-total @on-change="tapPage" :page-size="page.pageSize" />
  53. </div>
  54. </Card>
  55. <Modal v-model="sendModel" title="添加商品" @on-ok="sendOk('sendFormValidate')" @on-cancel="sendCancel" width="900">
  56. <Form :model="sendData" :label-width="labelWidth" :rules="ruleValidate" ref="sendFormValidate">
  57. <FormItem label="商品名称" prop="name">
  58. <Input v-model="sendData.name" type="text" placeholder="请输入商品名称"></Input>
  59. </FormItem>
  60. <FormItem label="兑换积分" prop="points">
  61. <Input v-model="sendData.name" type="number" placeholder="请输入兑换积分"></Input>
  62. </FormItem>
  63. <FormItem label="商品库存" prop="stock">
  64. <Input v-model="sendData.stock" type="number" placeholder="请输入商品库存"></Input>
  65. </FormItem>
  66. <FormItem label="封面图片" prop="image">
  67. <div class="clearfix">
  68. <div class="upimg-item fx-r fx-bc fx-ac" style="" v-if="sendData.image">
  69. <img v-lazy="sendData.image" :src="sendData.image" v-image-preview />
  70. <i class="el-icon-error img-remove-btn" @click="removeImg(index)"></i>
  71. </div>
  72. <ui-upload style="float: left;" :upUrl="upUrl" fileName="上传图片" :headers="upHeaders"
  73. :updata="{isz:0,code:'goods'}" @onUpload="onUpload" v-if="sendData.image == ''"></ui-upload>
  74. </div>
  75. </FormItem>
  76. <FormItem label="图片" prop="imgs">
  77. <div class="clearfix">
  78. <div class="upimg-item fx-r fx-bc fx-ac" style="" v-for="(item,index) in sendData.imgs"
  79. :key="index">
  80. <img v-lazy="item" :src="item" v-image-preview />
  81. <i class="el-icon-error img-remove-btn" @click="removeImgs(index)"></i>
  82. </div>
  83. <ui-upload style="float: left;" :upUrl="upUrl" fileName="上传图片" :headers="upHeaders"
  84. :updata="{isz:0,code:'goods'}" @onUpload="onUploads"
  85. v-if="sendData.imgs.length<6"></ui-upload>
  86. </div>
  87. </FormItem>
  88. <FormItem label="商品详情" prop="content">
  89. <Toolbar style="border: 1px solid #ccc" :editor="editor" :defaultConfig="toolbarConfig" />
  90. <!-- 编辑器 -->
  91. <Editor style="height: 400px; overflow-y: hidden;border: 1px solid #ccc;"
  92. :defaultConfig="editorConfig" v-model="sendData.content" @onChange="onChange"
  93. @onCreated="onCreated" />
  94. </FormItem>
  95. </Form>
  96. <div slot="footer">
  97. <Button size="large" :loading="modal_loading" @click="sendCancel">取消</Button>
  98. <Button type="primary" size="large" :loading="modal_loading"
  99. @click="sendOk('sendFormValidate')">提交</Button>
  100. </div>
  101. </Modal>
  102. </div>
  103. </template>
  104. <script>
  105. import axios from 'axios'
  106. import {
  107. DomEditor
  108. } from '@wangeditor/editor'
  109. import {
  110. Editor,
  111. Toolbar
  112. } from '@wangeditor/editor-for-vue'
  113. import IPageHeader from "../../../layouts/system/page-header/index";
  114. import {
  115. SystemShowTemplateList
  116. } from "../../../api/system/user";
  117. import Setting from '@/setting';
  118. import UiUpload from "@/ui/upload/index";
  119. import {
  120. upLoad
  121. } from '../../../api/system/sys'
  122. export default {
  123. name: "pointsList",
  124. components: {
  125. SystemShowTemplateList,
  126. IPageHeader,
  127. UiUpload,
  128. Editor,
  129. Toolbar
  130. },
  131. computed: {},
  132. data() {
  133. return {
  134. editor: null,
  135. toolbarConfig: {
  136. // toolbarKeys: [ /* 显示哪些菜单,如何排序、分组 */ ],
  137. excludeKeys: ['group-video', 'emotion', 'fullScreen'],
  138. },
  139. editorConfig: {
  140. placeholder: "请输入内容...",
  141. // autoFocus: false,
  142. // 所有的菜单配置,都要在 MENU_CONF 属性下
  143. MENU_CONF: {
  144. uploadImage: {
  145. },
  146. },
  147. },
  148. modal_loading: false,
  149. ruleValidate: {
  150. name: [{
  151. required: true,
  152. message: '请输入商品名称',
  153. trigger: 'blur'
  154. }],
  155. content: [{
  156. required: true,
  157. message: '请输入商品详情',
  158. trigger: 'blur'
  159. }],
  160. stock: [{
  161. required: true,
  162. message: '请输入商品库存',
  163. trigger: 'blur'
  164. }],
  165. image: [{
  166. required: true,
  167. message: '请上传封面图片'
  168. }],
  169. imgs: [{
  170. required: true,
  171. message: '请上传轮播图片'
  172. }],
  173. points: [{
  174. required: true,
  175. message: '请输入兑换积分',
  176. trigger: 'blur'
  177. }],
  178. },
  179. labelWidth: 120,
  180. upHeaders: {},
  181. upUrl: '',
  182. sendData: {
  183. points: '',
  184. stock: '',
  185. name: '',
  186. content: '',
  187. image: '',
  188. imgs: []
  189. },
  190. sendModel: false,
  191. pageTitle: "积分商品",
  192. options: {
  193. shortcuts: [{
  194. text: '今天',
  195. value() {
  196. const end = new Date();
  197. const start = new Date();
  198. start.setTime(new Date(new Date().getFullYear(), new Date().getMonth(), new Date()
  199. .getDate()));
  200. return [start, end];
  201. }
  202. },
  203. {
  204. text: '昨天',
  205. value() {
  206. const end = new Date();
  207. const start = new Date();
  208. start.setTime(start.setTime(new Date(new Date().getFullYear(), new Date().getMonth(),
  209. new Date().getDate() - 1)));
  210. end.setTime(end.setTime(new Date(new Date().getFullYear(), new Date().getMonth(),
  211. new Date().getDate())));
  212. return [start, end];
  213. }
  214. },
  215. {
  216. text: '最近7天',
  217. value() {
  218. const end = new Date();
  219. const start = new Date();
  220. start.setTime(start.setTime(new Date(new Date().getFullYear(), new Date().getMonth(),
  221. new Date().getDate() - 6)));
  222. return [start, end];
  223. }
  224. },
  225. {
  226. text: '最近30天',
  227. value() {
  228. const end = new Date();
  229. const start = new Date();
  230. start.setTime(start.setTime(new Date(new Date().getFullYear(), new Date().getMonth(),
  231. new Date().getDate() - 29)));
  232. return [start, end];
  233. }
  234. },
  235. {
  236. text: '本月',
  237. value() {
  238. const end = new Date();
  239. const start = new Date();
  240. start.setTime(start.setTime(new Date(new Date().getFullYear(), new Date().getMonth(),
  241. 1)));
  242. return [start, end];
  243. }
  244. },
  245. {
  246. text: '本年',
  247. value() {
  248. const end = new Date();
  249. const start = new Date();
  250. start.setTime(start.setTime(new Date(new Date().getFullYear(), 0, 1)));
  251. return [start, end];
  252. }
  253. }
  254. ]
  255. },
  256. orderData: {
  257. uid: "",
  258. status: "all",
  259. time: [],
  260. mobile: "",
  261. show_template_id: "",
  262. },
  263. columns: [{
  264. title: 'ID',
  265. align: 'center',
  266. key: 'id',
  267. align: 'center'
  268. },
  269. {
  270. title: '商品封面',
  271. align: 'center',
  272. slot: 'imgs',
  273. align: 'center'
  274. },
  275. {
  276. title: '商品名',
  277. key: 'name',
  278. align: 'center'
  279. },
  280. {
  281. title: '积分',
  282. align: 'center',
  283. key: 'points',
  284. align: 'left'
  285. },
  286. {
  287. title: '时间',
  288. align: 'center',
  289. key: 'add_time',
  290. align: 'left'
  291. },
  292. {
  293. title: '操作',
  294. align: 'center',
  295. slot: 'handle',
  296. align: 'left'
  297. },
  298. ],
  299. loading: false,
  300. orderList: [],
  301. orderDatalist: {},
  302. orderId: 0,
  303. page: {
  304. total: 0, // 总条数
  305. page: 1, // 当前页
  306. pageSize: 10 // 每页显示条数
  307. },
  308. }
  309. },
  310. created() {
  311. if (this.$route.query.title) {
  312. this.pageTitle = this.$route.query.title;
  313. }
  314. if (this.$route.query.uid) {
  315. this.orderData.uid = parseInt(this.$route.query.uid);
  316. }
  317. if (this.$route.query.show_template_id) {
  318. this.orderData.show_template_id = parseInt(this.$route.query.show_template_id);
  319. }
  320. this.initView();
  321. },
  322. methods: {
  323. onCreated(editor) {
  324. this.editor = Object.seal(editor); // 【注意】一定要用 Object.seal() 否则会报错
  325. console.log(this.editor.getMenuConfig());
  326. },
  327. onChange(editor) {
  328. console.log("onChange", editor.getHtml()); // onChange 时获取编辑器最新内容
  329. },
  330. getEditorText() {
  331. const editor = this.editor;
  332. if (editor == null) return;
  333. console.log(editor.getText()); // 执行 editor API
  334. },
  335. printEditorHtml() {
  336. const editor = this.editor;
  337. if (editor == null) return;
  338. console.log(editor.getHtml()); // 执行 editor API
  339. },
  340. initView: function() {
  341. let that = this
  342. var upHeaders = {};
  343. this.upUrl = Setting.apiBaseURL + "/systemv1/upload/index";
  344. const token = this.$utils.util.cookies.get('system_token');
  345. if (token) {
  346. upHeaders['SYSTEM-ACC-TOKEN'] = token;
  347. }
  348. this.upHeaders = upHeaders;
  349. this.editorConfig.MENU_CONF['uploadImage'] = {
  350. async customUpload(file, insertFn) {
  351. const formData = new FormData()
  352. formData.append('file', file)
  353. formData.append('code', 'good')
  354. formData.append('isz', '0')
  355. // formData.append('sign', this.generateSign(file.name)) // 自定义签名
  356. try {
  357. // const response = await axios.post(that.upUrl, formData, {
  358. // headers: {
  359. // 'SYSTEM-ACC-TOKEN': token
  360. // }
  361. // })
  362. upLoad(formData).then(res => {
  363. insertFn(res.data.img)
  364. })
  365. // if (response.data.success) {
  366. // // 插入图片到编辑器
  367. // }
  368. } catch (error) {
  369. console.error('上传失败:', error)
  370. }
  371. }
  372. }
  373. },
  374. onUpload: function(res) {
  375. if (res.code == -1) {
  376. Notice.error({
  377. title: "系统提示",
  378. content: res.msg
  379. });
  380. } else {
  381. this.sendData.image = res.data.img;
  382. }
  383. },
  384. onUploads: function(res) {
  385. if (res.code == -1) {
  386. Notice.error({
  387. title: "系统提示",
  388. content: res.msg
  389. });
  390. } else {
  391. this.sendData.imgs.push(res.data.img);
  392. }
  393. },
  394. removeImgs: function(index) {
  395. // this.$delete(this.sendData.imgs, index);
  396. },
  397. removeImg: function(index) {
  398. // this.$delete(this.sendData.imgs, index);
  399. this.sendData.image = ''
  400. },
  401. sendOpen() {
  402. this.sendModel = true
  403. },
  404. sendCancel() {
  405. this.sendModel = false
  406. this.sendData = {
  407. content: '',
  408. imgs: []
  409. }
  410. console.log('sendCancel');
  411. },
  412. sendOk(name) {
  413. console.log(this.sendData.content);
  414. this.$refs[name].validate((valid) => {
  415. if (valid) {
  416. this.sendCancel()
  417. this.$Message.success('发布成功!');
  418. } else {}
  419. })
  420. },
  421. tabsHandleClick: function(tab, event) {
  422. this.page.page = 1;
  423. this.getData();
  424. },
  425. orderSearch: function() {
  426. this.page.page = 1;
  427. this.getData();
  428. },
  429. /**
  430. * 分页
  431. */
  432. tapPage: function(index) {
  433. this.page.page = index;
  434. this.getData();
  435. },
  436. /**
  437. * 获取数据
  438. */
  439. getData: function() {
  440. var that = this;
  441. // this.loading = true;
  442. var data = {
  443. page: that.page.page,
  444. ...that.orderData
  445. };
  446. // SystemShowTemplateList(data)
  447. // .then(res=>{
  448. // that.loading = false;
  449. // if(res.code == 200) {
  450. // that.orderList = res.data.list;
  451. // that.page.pageSize = res.data.pageSize;
  452. // that.page.count = res.data.pageCount;
  453. // } else {
  454. // that.$alert(res.msg);
  455. // }
  456. // })
  457. // .catch(err=>{
  458. // that.loading = false;
  459. // that.$alert("网络繁忙,加载失败,请稍等片刻在尝试!", '系统提示');
  460. // });
  461. },
  462. }
  463. }
  464. </script>
  465. <style src="@wangeditor/editor/dist/css/style.css"></style>
  466. <style scoped>
  467. @import "~vue2-editor/dist/vue2-editor.css";
  468. .upimg-item {
  469. width: 82px;
  470. height: 82px;
  471. margin-right: 5px;
  472. overflow: hidden;
  473. float: left;
  474. margin-bottom: 5px;
  475. position: relative;
  476. }
  477. .upimg-item img {
  478. width: 82px;
  479. cursor: pointer;
  480. }
  481. .img-remove-btn {
  482. position: absolute;
  483. top: 0px;
  484. right: 0px;
  485. font-size: 24px;
  486. }
  487. </style>