appletView.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. <template>
  2. <div class="page-box">
  3. <moduleView :propConfig="config" ref="view" v-loading="load" @pagination="pagination" @onRefresh="getList" @resert="queryList" @search="queryList" @clickHandle="clickHandle" @modalHandle="modalHandle" @detail="detail" />
  4. <el-drawer
  5. size="50%"
  6. v-model="drawer"
  7. close-on-click-modal
  8. title="操作日志"
  9. direction="rtl"
  10. >
  11. <el-table ref="operlogRef" :data="logData">
  12. <el-table-column label="日志编号" align="center" prop="operId" width="130" />
  13. <el-table-column label="操作类型" align="center" prop="businessType">
  14. <template #default="scope">
  15. <dict-tag :options="sys_oper_type" :value="scope.row.businessType" />
  16. </template>
  17. </el-table-column>
  18. <el-table-column label="操作人员" align="center" width="110" prop="operName" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" />
  19. <el-table-column label="主机" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" />
  20. <el-table-column label="操作状态" align="center" prop="status">
  21. <template #default="scope">
  22. <dict-tag :options="sys_common_status" :value="scope.row.status" />
  23. </template>
  24. </el-table-column>
  25. <el-table-column label="操作日期" align="center" prop="operTime" width="180" sortable="custom" :sort-orders="['descending', 'ascending']">
  26. <template #default="scope">
  27. <span>{{ parseTime(scope.row.operTime) }}</span>
  28. </template>
  29. </el-table-column>
  30. </el-table>
  31. <div class="page-log">
  32. <el-pagination layout="prev, pager, next" :total="logPage.total" @current-change="handleCurrentChange"
  33. :current-page="logPage.pageNo" />
  34. </div>
  35. </el-drawer>
  36. </div>
  37. </template>
  38. <script setup>
  39. import { computed,getCurrentInstance,ref, shallowRef } from "vue";
  40. const { proxy } = getCurrentInstance();
  41. import {appList,addApp,updateApp,deleApp,disableApp,enableApp} from '@/api/base/shopManage'
  42. const { sys_oper_type, sys_common_status } = proxy.useDict("sys_oper_type","sys_common_status");
  43. import { list} from "@/api/monitor/operlog";
  44. import txt from "./txt.vue";
  45. // import merchant from "./merchant.vue";
  46. import stateRadio from "@/components/stateRadio/stateRadio.vue";
  47. const drawer = ref(false)
  48. const config = ref({
  49. attr:{
  50. calculateH:true
  51. },
  52. search:{
  53. attr:{
  54. size:'mini'
  55. },
  56. columns:[
  57. [{
  58. span:8,
  59. // label:'设备名称',
  60. labelWidth:1,
  61. prop:'searchText',
  62. component:'by-input',
  63. compConfig:{
  64. attr:{
  65. placeholder:'请输入小程序名称、应用ID、所属商户',
  66. prefixIcon:'vxe-icon-search'
  67. }
  68. }
  69. }]
  70. ]
  71. },
  72. tool:{
  73. tools:{
  74. // export:true,
  75. add:true,
  76. search:true,
  77. refresh:true
  78. },
  79. customTools:[{
  80. name: '导出',
  81. icon: 'bottom',
  82. event:{
  83. click:() =>{
  84. loadDown()
  85. }
  86. }
  87. }, {
  88. name: '操作日志',
  89. icon: 'Notebook',
  90. event:{
  91. click:() =>{
  92. drawer.value = true
  93. }
  94. }
  95. }]
  96. },
  97. table:{
  98. attr:{
  99. size:'mini',
  100. seq:true,
  101. align:'center',
  102. // checkbox:true
  103. },
  104. columns:[
  105. {
  106. isDetail:true,
  107. title:'小程序名称',
  108. field:'appName',
  109. },
  110. {
  111. title:'应用ID',
  112. field:'appkey',
  113. },
  114. {
  115. title:'所属商户',
  116. field:'commercialName'
  117. },
  118. {
  119. title:'状态',
  120. field:'state',
  121. component: 'textChange',
  122. compConfig:{
  123. attr:{
  124. data:[{
  125. label:'已启用',
  126. value:1,
  127. backgroundColor:'#f0f9eb',
  128. color:'#67c23a'
  129. },{
  130. label:'已禁用',
  131. value:0,
  132. backgroundColor:'#fef0f0',
  133. color:'#f56c6c'
  134. }]
  135. }
  136. }
  137. },
  138. {
  139. title:'创建时间',
  140. field:'createTime'
  141. },
  142. {
  143. title:'操作',
  144. action:true,
  145. plugins:[{
  146. name:'禁用',
  147. event:{
  148. show:row => {
  149. return row.state == 1
  150. },
  151. click:item => {
  152. disableHandle(item)
  153. }
  154. }
  155. },{
  156. name:'启用',
  157. event:{
  158. show:row => {
  159. return row.state == 0
  160. },
  161. click:item => {
  162. enableHandle(item)
  163. }
  164. }
  165. }]
  166. }]
  167. },
  168. modal:{
  169. tool:{
  170. tools:{
  171. return:true,
  172. add:true
  173. }
  174. },
  175. form:{
  176. attr:{
  177. width:'1000px',
  178. size:'small',
  179. labelWidth:'130px',
  180. rules:{
  181. appLogo:[
  182. {required: true, message: '请上传小程序logo', trigger: 'change'}
  183. ],
  184. appName:[
  185. {required: true, message: '请输入小程序名称', trigger: 'blur'}
  186. ],
  187. appIntroduce:[
  188. {required: true, message: '请输入小程序描述', trigger: 'blur'},
  189. ],
  190. commercialName:[
  191. {required: true, message: '请选择商户', trigger: 'change'}
  192. ],
  193. callBack:[
  194. {required: true, message: '请输入回调地址', trigger: 'blur'}
  195. ]
  196. }
  197. },
  198. columns:[
  199. [{
  200. label:'小程序logo',
  201. prop:'appLogo',
  202. component:'ByUpload'
  203. }],
  204. [{
  205. label:'小程序名称',
  206. prop:'appName',
  207. component:'by-input'
  208. }],
  209. [{
  210. label:'小程序描述',
  211. prop:'appIntroduce',
  212. component:'by-input',
  213. compConfig:{
  214. attr:{
  215. type:'textarea'
  216. }
  217. }
  218. }],
  219. [{
  220. label:'商户',
  221. prop:'commercialName',
  222. component:'by-select',
  223. compConfig:{
  224. attr:{
  225. label:'commercialName',
  226. value:'commercialId',
  227. retConfig:{
  228. commercialName:'commercialName',
  229. commercialId:'commercialId'
  230. },
  231. // disabledHandle: item => {
  232. // return item.state == 1 ? false : true
  233. // }
  234. },
  235. request:{
  236. url:'/app/getCommercialList',
  237. method:'get'
  238. }
  239. }
  240. }],
  241. [{
  242. label:'回调地址',
  243. prop:'callBack',
  244. component:'by-input',
  245. compConfig:{
  246. attr:{
  247. type:'textarea'
  248. }
  249. }
  250. }],
  251. [{
  252. label:'状态',
  253. prop:'state',
  254. component:shallowRef(stateRadio)
  255. }],
  256. [{
  257. label:'应用ID',
  258. prop:'appkey',
  259. component:shallowRef(txt)
  260. }],
  261. [{
  262. label:'应用秘钥',
  263. prop:'appSecret',
  264. component:shallowRef(txt)
  265. }],
  266. [{
  267. label:'备注',
  268. prop:'annotation',
  269. component:'by-input',
  270. compConfig:{
  271. attr:{
  272. type:'textarea'
  273. }
  274. }
  275. }]
  276. ]
  277. }
  278. }
  279. })
  280. const logData = ref([])
  281. const logPage = ref({
  282. pageNo: 1, //当前页
  283. pageSize: 20, //每页条数
  284. total: 0 //总条数
  285. })
  286. const load = ref(false)
  287. const isSearch = ref(false)
  288. const timeNum = ref(0);
  289. const initLog= () => {
  290. list({
  291. pageNum:logPage.value.pageNo,
  292. pageSize:logPage.value.pageSize,
  293. title:'小程序'
  294. }).then(res => {
  295. logData.value = res.rows;
  296. logPage.value.total = res.total;
  297. }).catch(()=> {
  298. })
  299. }
  300. //导出
  301. const loadDown = () => {
  302. let data = proxy.$refs.view.getQuery();
  303. data.pageNum = data.pageNo;
  304. delete data.pageNo;
  305. proxy.download('/app/export',data,`小程序_${new Date().getTime()}.xlsx`)
  306. }
  307. const handleCurrentChange = v => {
  308. logPage.value.pageNo = v;
  309. initLog()
  310. }
  311. // 禁用
  312. const disableHandle = item => {
  313. disableApp(item.appkey).then(() => {
  314. proxy.$message({
  315. message: '“' + item.appName + '”' + '已成功禁用!',
  316. type: 'success'
  317. })
  318. getList()
  319. initLog()
  320. }).catch(() => {})
  321. }
  322. //启用
  323. const enableHandle = item => {
  324. enableApp(item.appkey).then(() => {
  325. proxy.$message({
  326. message: '“' + item.appName + '”' + '已成功启用!',
  327. type: 'success'
  328. })
  329. getList()
  330. initLog()
  331. }).catch(() => {})
  332. }
  333. const detail = () => {
  334. config.value.modal.tool.tools.save = true;
  335. delete config.value.modal.tool.tools.add;
  336. proxy.$refs.view.initFormTool();
  337. }
  338. const clickHandle = n => {
  339. if(n == 'onAdd'){
  340. config.value.modal.tool.tools.add = true;
  341. delete config.value.modal.tool.tools.save;
  342. proxy.$refs.view.initFormTool();
  343. }
  344. if(n == 'onDelete'){
  345. delHandle()
  346. }
  347. }
  348. const modalHandle = n =>{
  349. if(n == 'onAdd'){
  350. proxy.$refs.view.getFormValidate(addData)
  351. }
  352. if(n == 'onSave'){
  353. proxy.$refs.view.getFormValidate(onSave)
  354. }
  355. }
  356. const delHandle = () => {
  357. let data = proxy.$refs.view.getSelectData();
  358. let ids = []
  359. if(!data && data.lenght == 0) {
  360. proxy.$message('请选择数据')
  361. return
  362. }
  363. for(const item of data) {
  364. ids.push(item.equipmentId)
  365. }
  366. proxy.$confirm('此操作将永久删除数据, 是否继续?', '提示', {
  367. confirmButtonText: '确定',
  368. cancelButtonText: '取消',
  369. type: 'warning'
  370. }).then(() => {
  371. load.value = true;
  372. deleApp({
  373. appKeys:appkey,
  374. }).then(()=>{
  375. proxy.$message({message:'删除成功!',type:'success'})
  376. load.value = false;
  377. getList();
  378. }).catch(()=>{
  379. load.value = false;
  380. })
  381. }).catch(()=>{})
  382. }
  383. //添加
  384. const addData = () => {
  385. let value = proxy.$refs.view.getFormValue();
  386. if(value){
  387. load.value = true;
  388. addApp(value).then(res =>{
  389. load.value = false;
  390. proxy.$message({
  391. message:res.msg,
  392. type:'success'
  393. });
  394. proxy.$refs.view.closeModal();
  395. getList();
  396. }).catch(()=>{
  397. load.value = false;
  398. })
  399. }
  400. }
  401. //保存
  402. const onSave = () => {
  403. let data = proxy.$refs.view.getFormValue();
  404. load.value = true;
  405. updateApp(data).then(res => {
  406. proxy.$message({
  407. message:res.msg,
  408. type:'success'
  409. });
  410. load.value = false;
  411. proxy.$refs.view.closeModal();
  412. pagination();
  413. }).catch(() => {
  414. load.value = false;
  415. })
  416. }
  417. const pagination = () => {
  418. if(isSearch.value){
  419. queryList();
  420. }else{
  421. getList()
  422. }
  423. }
  424. //列表请求(包含分页和搜素条件)
  425. const queryList = () => {
  426. isSearch.value = true;
  427. let data = proxy.$refs.view.getQuery();
  428. requestList(data);
  429. }
  430. const getList = () => {
  431. if(!proxy.$refs.view){
  432. if(timeNum.value > 5){
  433. return
  434. }
  435. setTimeout(()=>{
  436. getList()
  437. },500)
  438. timeNum.value ++;
  439. return
  440. }
  441. timeNum.value = 0;
  442. isSearch.value = false;
  443. let data = proxy.$refs.view.getPage();
  444. requestList(data);
  445. }
  446. const requestList = data => {
  447. load.value = true;
  448. data.pageNum = data.pageNo;
  449. delete data.pageNo;
  450. appList(data).then(res => {
  451. load.value = false;
  452. proxy.$refs.view.setTableValue(res.data.records);
  453. let page = {
  454. pageNo: res.data.current, //当前页
  455. pageSize: data.pageSize, //每页条数
  456. total: res.data.total //总条数
  457. };
  458. proxy.$refs.view.setPage(page)
  459. }).catch(()=>{
  460. load.value = false;
  461. })
  462. }
  463. nextTick(()=>{
  464. getList()
  465. })
  466. const calculateTable = () => {
  467. nextTick(() => {
  468. proxy.$refs.view.initTable()
  469. })
  470. }
  471. defineExpose({
  472. calculateTable
  473. })
  474. initLog()
  475. </script>
  476. <style scoped>
  477. .page-log{
  478. width: 100%;
  479. display: flex;
  480. justify-content: flex-end;
  481. }
  482. </style>