index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. <template>
  2. <div>
  3. <Card :bordered="false" dis-hover class="ivu-mt">
  4. <Form
  5. ref="formValidate"
  6. :model="formValidate"
  7. :label-width="labelWidth"
  8. :label-position="labelPosition"
  9. @submit.native.prevent
  10. >
  11. <!-- <Row type="flex" :gutter="24">
  12. <Col v-bind="grid">
  13. <FormItem label="状态:" label-for="status1">
  14. <Select v-model="status" placeholder="请选择" @on-change="userSearchs" clearable>
  15. <Option value="all">全部</Option>
  16. <Option value="1">开启</Option>
  17. <Option value="0">关闭</Option>
  18. </Select>
  19. </FormItem>
  20. </Col>
  21. <Col v-bind="grid">
  22. <FormItem label="搜索:" label-for="status2">
  23. <Input
  24. search
  25. enter-button
  26. placeholder="请输入账号"
  27. v-model="formValidate.name"
  28. @on-search="userSearchs"
  29. />
  30. </FormItem>
  31. </Col>
  32. </Row> -->
  33. <Row type="flex">
  34. <Col v-bind="grid">
  35. <Button v-auth="['setting-system_admin-add']" type="primary" @click="add" icon="md-add">添加账号</Button>
  36. </Col>
  37. </Row>
  38. </Form>
  39. <Table
  40. :columns="columns1"
  41. :data="list"
  42. class="mt25"
  43. no-userFrom-text="暂无数据"
  44. no-filtered-userFrom-text="暂无筛选结果"
  45. :loading="loading"
  46. highlight-row
  47. >
  48. <template slot-scope="{ row }" slot="roles">
  49. <div v-if="row.roles.length !== 0">
  50. <Tag color="blue" v-for="(item, index) in row.roles.split(',')" :key="index" v-text="item"></Tag>
  51. </div>
  52. </template>
  53. <template slot-scope="{ row }" slot="status">
  54. <i-switch
  55. v-model="row.status"
  56. :value="row.status"
  57. :true-value="1"
  58. :false-value="0"
  59. @on-change="onchangeIsShow(row)"
  60. size="large"
  61. >
  62. <span slot="open">开启</span>
  63. <span slot="close">关闭</span>
  64. </i-switch>
  65. </template>
  66. <template slot-scope="{ row, index }" slot="action">
  67. <a @click="setUp(row)">设置</a>
  68. <Divider type="vertical" />
  69. <a @click="edit(row)">编辑</a>
  70. <Divider type="vertical" />
  71. <a @click="del(row, '删除账号', index)">删除</a>
  72. </template>
  73. </Table>
  74. <div class="acea-row row-right page">
  75. <Page
  76. :total="total"
  77. :current="formValidate.page"
  78. show-elevator
  79. show-total
  80. @on-change="pageChange"
  81. :page-size="formValidate.limit"
  82. />
  83. </div>
  84. </Card>
  85. <Modal
  86. v-model="modals"
  87. scrollable
  88. :title="type == 0 ? '添加账号' : '编辑账号'"
  89. :mask-closable="false"
  90. width="700"
  91. :closable="false"
  92. >
  93. <Form
  94. ref="modalsdate"
  95. :model="modalsdate"
  96. :rules="type == 0 ? ruleValidate : editValidate"
  97. :label-width="70"
  98. label-position="right"
  99. >
  100. <FormItem label="账号" prop="appid">
  101. <div style="display: flex">
  102. <Input type="text" v-model="modalsdate.appid" :disabled="type != 0"></Input>
  103. </div>
  104. </FormItem>
  105. <FormItem label="密码" prop="appsecret">
  106. <div style="display: flex">
  107. <Input type="text" v-model="modalsdate.appsecret" class="input"></Input>
  108. <Button type="primary" @click="reset" class="reset">重置</Button>
  109. </div>
  110. </FormItem>
  111. <FormItem label="描述" prop="title">
  112. <div style="display: flex">
  113. <Input type="textarea" v-model="modalsdate.title"></Input>
  114. </div>
  115. </FormItem>
  116. <FormItem label="接口权限" prop="title">
  117. <!-- <CheckboxGroup v-model="modalsdate.rules">
  118. <Checkbox
  119. :disabled="[2, 3].includes(item.id)"
  120. style="width: 30%"
  121. v-for="item in intList"
  122. :key="item.id"
  123. :label="item.id"
  124. >{{ item.name }}</Checkbox
  125. >
  126. </CheckboxGroup> -->
  127. <Tree :data="intList" multiple show-checkbox ref="tree" @on-check-change="selectTree"></Tree>
  128. </FormItem>
  129. </Form>
  130. <div slot="footer">
  131. <Button type="primary" @click="ok('modalsdate')">确定</Button>
  132. <Button @click="cancel">取消</Button>
  133. </div>
  134. </Modal>
  135. <Modal v-model="settingModals" scrollable title="设置推送" :mask-closable="false" width="900" :closable="false">
  136. <Form
  137. class="setting-style"
  138. ref="settingData"
  139. :model="settingData"
  140. :rules="type == 0 ? ruleValidate : editValidate"
  141. :label-width="140"
  142. label-position="right"
  143. >
  144. <FormItem label="推送开关" prop="switch">
  145. <Switch v-model="settingData.push_open" :true-value="1" :false-value="0" />
  146. </FormItem>
  147. <FormItem label="推送账号" prop="push_account">
  148. <div class="form-content">
  149. <Input type="text" v-model="settingData.push_account" placeholder="请输入推送账号"></Input>
  150. <span class="trip">接受推送方获取token的账号</span>
  151. </div>
  152. </FormItem>
  153. <FormItem label="推送密码" prop="push_password">
  154. <div class="form-content">
  155. <Input type="text" v-model="settingData.push_password" placeholder="请输入推送密码"></Input>
  156. <span class="trip">接受推送方获取token的密码</span>
  157. </div>
  158. </FormItem>
  159. <FormItem label="获取TOKEN接口" prop="push_token_url">
  160. <div class="form-content">
  161. <div class="input-button">
  162. <Input type="text" v-model="settingData.push_token_url" placeholder="请输入获取TOKEN接口"></Input>
  163. <Button class="ml10" type="primary" @click="textOutUrl(settingData.id)">测试链接</Button>
  164. </div>
  165. <span class="trip"
  166. >接受推送方获取token的URL地址,POST方法,传入push_account和push_password,返回token和有效时间time(秒)</span
  167. >
  168. </div>
  169. </FormItem>
  170. <FormItem label="用户数据修改推送接口" prop="user_update_push">
  171. <div class="form-content">
  172. <Input type="text" v-model="settingData.user_update_push" placeholder="请输入用户数据修改推送接口"></Input>
  173. <span class="trip">用户修改积分,余额,经验等将用户信息推送至该地址,POST方法</span>
  174. </div>
  175. </FormItem>
  176. <FormItem label="订单创建推送接口" prop="order_create_push">
  177. <div class="form-content">
  178. <Input type="text" v-model="settingData.order_create_push" placeholder="请输入订单创建推送接口"></Input>
  179. <span class="trip">订单创建时推送订单信息至该地址,POST方法</span>
  180. </div>
  181. </FormItem>
  182. <FormItem label="订单支付推送接口" prop="order_pay_push">
  183. <div class="form-content">
  184. <Input type="text" v-model="settingData.order_pay_push" placeholder="请输入订单支付推送接口"></Input>
  185. <span class="trip">订单完成支付时推送订单已支付信息至该地址,POST方法</span>
  186. </div>
  187. </FormItem>
  188. <FormItem label="售后订单创建推送接口" prop="refund_create_push">
  189. <div class="form-content">
  190. <Input
  191. type="text"
  192. v-model="settingData.refund_create_push"
  193. placeholder="请输入售后订单创建推送接口"
  194. ></Input>
  195. <span class="trip">售后订单生成时推送售后单信息至该地址,POST方法</span>
  196. </div>
  197. </FormItem>
  198. <FormItem label="售后订单取消推送接口" prop="refund_cancel_push">
  199. <div class="form-content">
  200. <Input
  201. type="text"
  202. v-model="settingData.refund_cancel_push"
  203. placeholder="请输入售后订单取消推送接口"
  204. ></Input>
  205. <span class="trip">售后订单取消时推送售后单取消信息至该地址,POST方法</span>
  206. </div>
  207. </FormItem>
  208. </Form>
  209. <div slot="footer">
  210. <Button type="primary" @click="submit('settingData')">确定</Button>
  211. <Button @click="settingModals = false">取消</Button>
  212. </div>
  213. </Modal>
  214. </div>
  215. </template>
  216. <script>
  217. import { mapState } from 'vuex';
  218. import {
  219. accountListApi,
  220. outSaveApi,
  221. outSavesApi,
  222. setShowApi,
  223. outSetUp,
  224. interfaceList,
  225. setUpPush,
  226. textOutUrl,
  227. } from '@/api/systemOutAccount';
  228. export default {
  229. name: 'systemOut',
  230. data() {
  231. return {
  232. grid: {
  233. xl: 7,
  234. lg: 7,
  235. md: 12,
  236. sm: 24,
  237. xs: 24,
  238. },
  239. total: 0,
  240. loading: false,
  241. roleData: {
  242. status1: '',
  243. },
  244. formValidate: {
  245. roles: '',
  246. status: '',
  247. name: '',
  248. page: 1, // 当前页
  249. limit: 20, // 每页显示条数
  250. },
  251. status: '',
  252. list: [],
  253. intList: [],
  254. columns: [
  255. {
  256. type: 'selection',
  257. width: 60,
  258. align: 'center',
  259. },
  260. {
  261. title: '接口名称',
  262. key: 'name',
  263. },
  264. ],
  265. columns1: [
  266. {
  267. title: '编号',
  268. key: 'id',
  269. minWidth: 80,
  270. },
  271. {
  272. title: '账号',
  273. key: 'appid',
  274. minWidth: 150,
  275. },
  276. {
  277. title: '描述',
  278. key: 'title',
  279. minWidth: 250,
  280. },
  281. {
  282. title: '添加时间',
  283. key: 'add_time',
  284. minWidth: 180,
  285. },
  286. {
  287. title: '最后登录时间',
  288. key: 'last_time',
  289. minWidth: 180,
  290. },
  291. {
  292. title: '最后登录ip',
  293. key: 'ip',
  294. minWidth: 180,
  295. },
  296. {
  297. title: '状态',
  298. slot: 'status',
  299. minWidth: 90,
  300. },
  301. {
  302. title: '操作',
  303. key: 'action',
  304. slot: 'action',
  305. fixed: 'right',
  306. minWidth: 120,
  307. },
  308. ],
  309. FromData: null,
  310. modalTitleSs: '',
  311. ids: Number,
  312. modals: false,
  313. modalsid: '',
  314. type: 0,
  315. modalsdate: {
  316. appid: '',
  317. appsecret: '',
  318. title: '',
  319. rules: [],
  320. },
  321. settingModals: false,
  322. settingData: {
  323. switch: 1,
  324. name: '',
  325. },
  326. ruleValidate: {
  327. appid: [{ required: true, message: '请输入正确的账号 (4到30位之间)', trigger: 'blur', min: 4, max: 30 }],
  328. appsecret: [{ required: true, message: '请输入正确的密码 (6到32位之间)', trigger: 'blur', min: 6, max: 32 }],
  329. title: [{ message: '请输入正确的描述 (不能多于200位数)', trigger: 'blur', max: 200 }],
  330. },
  331. editValidate: {
  332. appsecret: [{ required: false, message: '请输入正确的密码 (6到32位之间)', trigger: 'blur', min: 6, max: 32 }],
  333. },
  334. };
  335. },
  336. computed: {
  337. ...mapState('media', ['isMobile']),
  338. labelWidth() {
  339. return this.isMobile ? undefined : 50;
  340. },
  341. labelPosition() {
  342. return this.isMobile ? 'top' : 'left';
  343. },
  344. },
  345. created() {
  346. this.getList();
  347. },
  348. methods: {
  349. // 开启状态
  350. onchangeIsShow(row) {
  351. let data = {
  352. id: row.id,
  353. status: row.status,
  354. };
  355. setShowApi(data)
  356. .then(async (res) => {
  357. this.$Message.success(res.msg);
  358. })
  359. .catch((res) => {
  360. this.$Message.error(res.msg);
  361. });
  362. },
  363. // 请求列表
  364. submitFail() {
  365. this.getList();
  366. },
  367. // 列表
  368. getList() {
  369. this.loading = true;
  370. this.formValidate.roles = this.formValidate.roles || '';
  371. accountListApi(this.formValidate)
  372. .then(async (res) => {
  373. this.total = res.data.count;
  374. this.list = res.data.list;
  375. this.loading = false;
  376. })
  377. .catch((res) => {
  378. this.loading = false;
  379. this.$Message.error(res.msg);
  380. });
  381. },
  382. pageChange(index) {
  383. this.formValidate.page = index;
  384. this.getList();
  385. },
  386. // 添加
  387. add() {
  388. this.modals = true;
  389. this.type = 0;
  390. this.modalsdate = {
  391. appid: '',
  392. appsecret: '',
  393. title: '',
  394. rules: [],
  395. };
  396. this.getIntList();
  397. },
  398. selectTree(e, i) {},
  399. getIntList(type, list) {
  400. interfaceList().then((res) => {
  401. this.intList = res.data;
  402. if (!type) {
  403. this.intList.map((item) => {
  404. if (item.id === 1) {
  405. item.checked = true;
  406. item.disableCheckbox = true;
  407. if (item.children.length) {
  408. item.children.map((v) => {
  409. v.checked = true;
  410. v.disableCheckbox = true;
  411. });
  412. }
  413. }
  414. });
  415. } else {
  416. list.map((item) => {
  417. this.intList.map((e) => {
  418. if (e.id === 1) {
  419. e.checked = true;
  420. e.disableCheckbox = true;
  421. if (e.children.length) {
  422. e.children.map((v) => {
  423. v.checked = true;
  424. v.disableCheckbox = true;
  425. });
  426. }
  427. }
  428. listData(e.children || [], item);
  429. });
  430. });
  431. }
  432. function listData(list, id) {
  433. if (list.length) {
  434. list.map((v) => {
  435. if (v.id == id) {
  436. v.checked = true;
  437. }
  438. if (v.children) {
  439. listData(v.children);
  440. }
  441. });
  442. }
  443. }
  444. });
  445. },
  446. // 编辑
  447. edit(row) {
  448. this.modals = true;
  449. this.modalsdate.appid = row.appid;
  450. this.modalsdate.title = row.title;
  451. this.modalsdate.rules = row.rules.map((e) => {
  452. return Number(e);
  453. });
  454. this.modalsid = row.id;
  455. this.type = 1;
  456. this.getIntList('edit', this.modalsdate.rules);
  457. },
  458. // 删除
  459. del(row, tit, num) {
  460. let delfromData = {
  461. title: tit,
  462. num: num,
  463. url: `setting/system_out_account/${row.id}`,
  464. method: 'DELETE',
  465. ids: '',
  466. };
  467. this.$modalSure(delfromData)
  468. .then((res) => {
  469. this.$Message.success(res.msg);
  470. this.list.splice(num, 1);
  471. })
  472. .catch((res) => {
  473. this.$Message.error(res.msg);
  474. });
  475. },
  476. // 编辑
  477. setUp(row) {
  478. this.settingModals = true;
  479. this.settingData = row;
  480. },
  481. // 搜索
  482. userSearchs() {
  483. this.formValidate.status = this.status === 'all' ? '' : this.status;
  484. this.formValidate.page = 1;
  485. this.list = [];
  486. this.getList();
  487. },
  488. submit(name) {
  489. setUpPush(this.settingData).then((res) => {
  490. this.$Message.success(res.msg);
  491. this.settingModals = false;
  492. this.getList();
  493. });
  494. },
  495. textOutUrl() {
  496. textOutUrl(this.settingData)
  497. .then((res) => {
  498. this.$Message.success(res.msg);
  499. })
  500. .catch((err) => {
  501. this.$Message.error(err.msg);
  502. });
  503. },
  504. ok(name) {
  505. let fuc = this.modalsid ? outSavesApi : outSaveApi;
  506. this.$refs[name].validate((valid) => {
  507. if (valid) {
  508. this.modalsdate.rules = [];
  509. this.$refs.tree.getCheckedAndIndeterminateNodes().map((node) => {
  510. this.modalsdate.rules.push(node.id);
  511. });
  512. if (this.modalsid) this.modalsdate.id = this.modalsid;
  513. fuc(this.modalsdate)
  514. .then((res) => {
  515. this.modalsdate = {
  516. appid: '',
  517. appsecret: '',
  518. title: '',
  519. rules: [],
  520. };
  521. (this.modals = false), this.$Message.success(res.msg);
  522. this.modalsid = '';
  523. this.getList();
  524. })
  525. .catch((err) => {
  526. this.$Message.error(err.msg);
  527. });
  528. } else {
  529. this.$Message.warning('请完善数据');
  530. }
  531. });
  532. },
  533. cancel() {
  534. this.modalsid = '';
  535. this.modalsdate = {
  536. appid: '',
  537. appsecret: '',
  538. title: '',
  539. };
  540. this.modals = false;
  541. },
  542. reset() {
  543. let len = 16;
  544. let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
  545. let maxPos = chars.length;
  546. let pwd = '';
  547. for (let i = 0; i < len; i++) {
  548. pwd += chars.charAt(Math.floor(Math.random() * maxPos));
  549. }
  550. this.modalsdate.appsecret = pwd;
  551. },
  552. },
  553. };
  554. </script>
  555. <style scoped>
  556. .reset {
  557. margin-left: 10px;
  558. }
  559. .form-content {
  560. display: flex;
  561. flex-direction: column;
  562. }
  563. .input-button {
  564. display: flex;
  565. }
  566. w .trip {
  567. color: #aaa;
  568. line-height: 20px;
  569. }
  570. .setting-style /deep/ .ivu-form-item {
  571. margin-bottom: 14px;
  572. }
  573. </style>