Automate.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. <template>
  2. <div class="automate-container">
  3. <div class="header">
  4. <div class="title">
  5. <template v-if="!touchStatus">我的工程</template>
  6. <template v-else>
  7. <div class="back" @click="touchStatus = false"><van-icon name="arrow-left" />返回工程</div></template
  8. >
  9. </div>
  10. <div class="btn-group">
  11. <van-button v-show="!touchStatus" size="small" type="warning" @click="importProject" style="margin-right: 8px"
  12. >工程导入</van-button
  13. >
  14. <van-button v-show="!touchStatus" size="small" type="primary" @click="popupShow = true">新建工程</van-button>
  15. </div>
  16. </div>
  17. <div class="project-container">
  18. <van-checkbox-group v-model="checked" @change="handleCheckedChange">
  19. <van-swipe-cell v-for="item in projectList" :key="item.id" :disabled="touchStatus">
  20. <van-cell
  21. clickable
  22. :border="false"
  23. :title="item.name"
  24. :label="item.time"
  25. @click="!touchStatus && router.push(`/project-info/${item.id}`)"
  26. @touchstart="handleTouchStart"
  27. @touchmove="handleTouchMove"
  28. @touchend="handleTouchEnd"
  29. >
  30. <template #value>
  31. <van-checkbox :name="item.id" @click.stop="" shape="square" v-show="touchStatus"></van-checkbox>
  32. </template>
  33. </van-cell>
  34. <template #right>
  35. <van-button square type="danger" text="删除" class="del-button" @click="handleDelete([item.id])" />
  36. </template>
  37. </van-swipe-cell>
  38. </van-checkbox-group>
  39. </div>
  40. <div class="del-btn" v-show="touchStatus">
  41. <van-button type="danger" block @click="handleDelete(checked)">删除文件</van-button>
  42. </div>
  43. <van-popup v-model:show="popupShow" round :style="{ width: '80%' }">
  44. <div class="label" style="margin: 16px">新建工程</div>
  45. <van-form @submit="onSubmit">
  46. <van-cell-group inset>
  47. <van-field
  48. border
  49. v-model="newProjectName"
  50. name="newProjectName"
  51. placeholder="工程名称"
  52. maxlength="20"
  53. :rules="[{ required: true, message: '请填写工程名称' }]"
  54. />
  55. </van-cell-group>
  56. <div class="van-button-group">
  57. <van-button @click="handleCancel" size="small">取消</van-button>
  58. <van-button type="primary" native-type="submit" size="small">确定</van-button>
  59. </div>
  60. </van-form>
  61. </van-popup>
  62. </div>
  63. </template>
  64. <script setup lang="ts">
  65. import { useGlobalStore } from '@/stores/global'
  66. import { storeToRefs } from 'pinia'
  67. const { projectList } = storeToRefs(useGlobalStore())
  68. const router = useRouter()
  69. const checked = ref([])
  70. const handleCheckedChange = (names: string[]) => {
  71. console.log(names)
  72. }
  73. let touchTimer: any
  74. const touchStatus = ref(false)
  75. const handleTouchStart = () => {
  76. touchTimer = setTimeout(() => {
  77. touchStatus.value = true
  78. }, 700)
  79. }
  80. const handleTouchMove = () => {
  81. if (touchTimer) {
  82. clearTimeout(touchTimer)
  83. touchTimer = 0
  84. }
  85. }
  86. const handleTouchEnd = () => {
  87. if (touchTimer) {
  88. clearTimeout(touchTimer)
  89. touchTimer = 0
  90. }
  91. }
  92. const handleDelete = (val: string[]) => {
  93. if (val.length) {
  94. projectList.value = projectList.value.filter((item) => !val.includes(item.id))
  95. checked.value = []
  96. if (projectList.value.length === 0) {
  97. touchStatus.value = false
  98. }
  99. }
  100. }
  101. const popupShow = ref(false)
  102. const newProjectName = ref('')
  103. const onSubmit = (values: Record<string, string>) => {
  104. console.log(values)
  105. const isExist = projectList.value.some((item) => item.name === values.newProjectName)
  106. if (isExist) {
  107. showFailToast('工程名称已存在')
  108. return
  109. } else {
  110. const id = Date.now() + ''
  111. projectList.value.unshift({
  112. name: values.newProjectName,
  113. id,
  114. time: new Date().toLocaleString(),
  115. commandList: [
  116. {
  117. id: Date.now() + '',
  118. name: '任务1',
  119. parentId: id,
  120. stepList: [],
  121. time: new Date().toLocaleString(),
  122. // x: 100,
  123. // y: 100
  124. }
  125. ],
  126. isCompiled: false,
  127. CompileTime: ''
  128. })
  129. handleCancel()
  130. }
  131. }
  132. const handleCancel = async () => {
  133. popupShow.value = false
  134. await nextTick()
  135. newProjectName.value = ''
  136. }
  137. const wx = window.wx
  138. const initWxEnv = () => {
  139. if (!window.isInWx) return showFailToast('请在微信中打开')
  140. const url = location.origin + location.pathname + location.search
  141. const wxConfigStr = localStorage.getItem(url)
  142. if (!wxConfigStr) showFailToast('初始化失败')
  143. else {
  144. const wxConfig = JSON.parse(wxConfigStr)
  145. wx.config(wxConfig)
  146. wx.ready(function () {
  147. console.log('微信初始化成功')
  148. })
  149. wx.error(function (res: any) {
  150. console.log('微信初始化失败', res)
  151. })
  152. }
  153. }
  154. initWxEnv()
  155. const importProject = () => {
  156. // if (!window.isInWx) return
  157. const inputEl = document.createElement('input')
  158. inputEl.type = 'file'
  159. inputEl.accept = '.jmpec'
  160. inputEl.onchange = (e) => {
  161. console.dir(e.target!)
  162. if (!e.target) return
  163. const files = (e.target as HTMLInputElement).files
  164. if (!files || !files?.length) return
  165. const file = files[0]
  166. const fileType = file.name.slice(-6)
  167. if (fileType !== '.jmpec') return showFailToast('文件类型错误!')
  168. const reader = new FileReader()
  169. reader.onload = (e) => {
  170. if (!e.target) return
  171. const projectStr = e.target.result as string
  172. console.log(projectStr)
  173. try {
  174. const newProject = JSON.parse(projectStr)
  175. if (newProject.qrcodeType !== 'worldflying_plc_editor') return showFailToast('导入失败!')
  176. const isExist = projectList.value.some((item) => item.name === newProject.name)
  177. if (isExist) {
  178. showFailToast('工程名称已存在')
  179. return
  180. }
  181. newProject.id = Date.now() + ''
  182. newProject.time = new Date().toLocaleString()
  183. newProject.isCompiled = false
  184. newProject.CompileTime = ''
  185. projectList.value.unshift(newProject)
  186. showSuccessToast('导入成功')
  187. } catch (error) {
  188. showFailToast('导入失败')
  189. }
  190. }
  191. reader.readAsText(file)
  192. }
  193. inputEl.click()
  194. inputEl.remove()
  195. // wx.scanQRCode({
  196. // needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
  197. // scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有
  198. // success: function (res: any) {
  199. // if (res.errMsg !== 'scanQRCode:ok') return showFailToast('扫描失败')
  200. // const projectStr = res.resultStr
  201. // try {
  202. // const newProject = JSON.parse(projectStr)
  203. // if (newProject.qrcodeType !== 'worldflying_plc_editor') return showFailToast('扫描失败')
  204. // const isExist = projectList.value.some((item) => item.name === newProject.name)
  205. // if (isExist) {
  206. // showFailToast('工程名称已存在')
  207. // return
  208. // }
  209. // newProject.id = Date.now() + ''
  210. // newProject.time = new Date().toLocaleString()
  211. // newProject.isCompiled = false
  212. // newProject.CompileTime = ''
  213. // projectList.value.unshift(newProject)
  214. // showSuccessToast('导入成功')
  215. // } catch (error) {
  216. // showFailToast('扫描失败')
  217. // }
  218. // }
  219. // })
  220. }
  221. </script>
  222. <style scoped>
  223. .automate-container {
  224. padding: 16px 0 0;
  225. height: 100%;
  226. overflow: hidden;
  227. }
  228. .header {
  229. padding: 0 16px 16px;
  230. display: flex;
  231. justify-content: space-between;
  232. align-items: center;
  233. }
  234. .del-button {
  235. height: 100%;
  236. }
  237. .van-cell {
  238. justify-content: space-between;
  239. align-items: center;
  240. margin-bottom: 2px;
  241. gap: 16px;
  242. }
  243. .project-container {
  244. height: calc(100% - 48px);
  245. padding-bottom: 16px;
  246. overflow: auto;
  247. }
  248. .project-container :deep(.van-cell__value) {
  249. width: 32px;
  250. flex: none;
  251. }
  252. .project-container :deep(.van-cell__title) {
  253. overflow: hidden;
  254. white-space: nowrap;
  255. text-overflow: ellipsis;
  256. }
  257. .del-btn {
  258. position: fixed;
  259. bottom: 84px;
  260. left: 50%;
  261. transform: translateX(-50%);
  262. width: 70%;
  263. }
  264. :deep(.van-field) {
  265. padding-left: 0;
  266. }
  267. :deep(.van-field__body) {
  268. border-bottom: 1px solid #eaeaea;
  269. }
  270. .van-button-group {
  271. margin: 16px;
  272. display: flex;
  273. justify-content: flex-end;
  274. gap: 8px;
  275. }
  276. </style>