Conditions.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. <template>
  2. <div class="props">
  3. <div
  4. v-if="data.conditions && data.conditions.length > 0"
  5. class="form-item banner"
  6. >
  7. <label>触发条件</label>
  8. <div class="w-full flex middle between">
  9. <div></div>
  10. <t-radio-group v-model="data.conditionType">
  11. <t-radio value="and"> 满足全部条件 </t-radio>
  12. <t-radio value="or"> 满足任意条件 </t-radio>
  13. </t-radio-group>
  14. </div>
  15. </div>
  16. <div v-for="(c, index) in data.conditions" class="mb-12">
  17. <div class="flex middle between head">
  18. <div class="flex middle">
  19. <t-icon name="arrow-right" class="mr-4" />
  20. 条件{{ index + 1 }}
  21. </div>
  22. <t-icon
  23. name="close"
  24. class="hover"
  25. @click="data.conditions.splice(index, 1)"
  26. />
  27. </div>
  28. <div class="">
  29. <div class="form-item mt-4">
  30. <label>条件类型</label>
  31. <t-radio-group v-model="c.type">
  32. <t-radio value=""> 关系条件 </t-radio>
  33. <t-radio value="fn"> 高级条件 </t-radio>
  34. </t-radio-group>
  35. </div>
  36. <template v-if="!c.type">
  37. <div class="form-item mt-8">
  38. <label>属性名</label>
  39. <t-select-input
  40. v-model:inputValue="c.key"
  41. :value="c.keyLabel"
  42. v-model:popupVisible="c.keyPopupVisible"
  43. allow-input
  44. clearable
  45. @clear="c.keyLabel = undefined"
  46. @focus="c.keyPopupVisible = true"
  47. @blur="c.keyPopupVisible = undefined"
  48. @input-change="onKeyInput(c)"
  49. class="shrink-0"
  50. style="width: 152px"
  51. >
  52. <template #panel>
  53. <ul style="padding: 8px 12px">
  54. <li
  55. v-for="item in cprops"
  56. :key="item.value"
  57. @click="
  58. c.key = item.value;
  59. c.keyLabel = item.label;
  60. "
  61. >
  62. {{ item.label }}
  63. </li>
  64. </ul>
  65. </template>
  66. </t-select-input>
  67. </div>
  68. <div class="form-item mt-8">
  69. <label>关系运算</label>
  70. <t-select
  71. v-model="c.operator"
  72. placeholder="关系运算"
  73. :options="operatorOptions"
  74. clearable
  75. class="shrink-0"
  76. />
  77. </div>
  78. <div class="form-item mt-8">
  79. <label>运算对象</label>
  80. <t-select
  81. v-model="c.valueType"
  82. class="shrink-0"
  83. placeholder="固定值"
  84. >
  85. <t-option key="" value="" label="固定值"> 固定值 </t-option>
  86. <t-option key="prop" value="prop" label="对象属性值">
  87. 对象属性值
  88. </t-option>
  89. </t-select>
  90. </div>
  91. <div v-if="!c.valueType" class="form-item mt-8 form-item-valueType">
  92. <label>值</label>
  93. <t-input v-model="c.value" class="shrink-0" style="width: 320px" />
  94. </div>
  95. <template v-else>
  96. <div class="form-item mt-8">
  97. <label>对象</label>
  98. <t-tree-select
  99. v-model="c.target"
  100. :data="penTree"
  101. filterable
  102. placeholder="对象"
  103. class="shrink-0"
  104. @change="onChangeTriggerTarget(c)"
  105. />
  106. </div>
  107. <div class="form-item mt-8">
  108. <label>属性</label>
  109. <t-select-input
  110. v-model:inputValue="c.value"
  111. :value="c.label"
  112. v-model:popupVisible="c.popupVisible"
  113. allow-input
  114. clearable
  115. @clear="c.label = undefined"
  116. @focus="c.popupVisible = true"
  117. @blur="c.popupVisible = undefined"
  118. @input-change="onInput(c)"
  119. class="shrink-0"
  120. >
  121. <template #panel>
  122. <ul style="padding: 8px 12px">
  123. <li
  124. v-for="item in cprops"
  125. :key="item.value"
  126. @click="
  127. c.value = item.value;
  128. c.label = item.label;
  129. "
  130. >
  131. {{ item.label }}
  132. </li>
  133. </ul>
  134. </template>
  135. </t-select-input>
  136. </div>
  137. </template>
  138. </template>
  139. <template v-else>
  140. <div>function condition(pen) {</div>
  141. <CodeEditor class="mt-4" v-model="c.fnJs" />
  142. <div class="mt-4">}</div>
  143. </template>
  144. </div>
  145. </div>
  146. <div class="mt-8">
  147. <a @click="addTriggerCondition(data)"> + 添加触发条件 </a>
  148. </div>
  149. </div>
  150. </template>
  151. <script lang="ts" setup>
  152. import { onBeforeMount, ref } from 'vue';
  153. import CodeEditor from '@/views/components/common/CodeEditor.vue';
  154. import { getPenTree, typeOptions } from '@/services/common';
  155. const penTree: any = ref([]);
  156. const { data } = defineProps<{
  157. data: any;
  158. }>();
  159. onBeforeMount(() => {
  160. if (!data.conditions) {
  161. data.conditions = [];
  162. }
  163. penTree.value = getPenTree();
  164. });
  165. const onChangeTriggerTarget = (c: any) => {
  166. // c.targetProps = [
  167. // {
  168. // value: 'x',
  169. // label: 'X',
  170. // },
  171. // {
  172. // value: 'y',
  173. // label: 'Y',
  174. // },
  175. // {
  176. // value: 'width',
  177. // label: '宽',
  178. // },
  179. // {
  180. // value: 'height',
  181. // label: '高',
  182. // },
  183. // {
  184. // value: 'visible',
  185. // label: '显示',
  186. // },
  187. // {
  188. // value: 'text',
  189. // label: '文字',
  190. // },
  191. // {
  192. // value: 'progress',
  193. // label: '进度',
  194. // },
  195. // {
  196. // value: 'showChild',
  197. // label: '状态',
  198. // },
  199. // {
  200. // value: 'rotate',
  201. // label: '旋转',
  202. // },
  203. // ];
  204. const target: any = meta2d.findOne(c.target);
  205. if (target && target.realTimes) {
  206. for (const item of target.realTimes) {
  207. const found = cprops.findIndex((elem: any) => elem.value === item.key);
  208. if (found < 0) {
  209. cprops.push({
  210. value: item.key,
  211. label: item.label,
  212. });
  213. }
  214. }
  215. }
  216. };
  217. const addTriggerCondition = (data: any) => {
  218. data.conditions.push({
  219. type: '',
  220. operator: '=',
  221. valueType: '',
  222. });
  223. };
  224. const onKeyInput = (item: any) => {
  225. item.keyLabel = item.key;
  226. };
  227. const onInput = (item: any) => {
  228. item.label = item.value;
  229. };
  230. const cprops = ref<any>([
  231. {
  232. value: 'x',
  233. label: 'X',
  234. },
  235. {
  236. value: 'y',
  237. label: 'Y',
  238. },
  239. {
  240. value: 'width',
  241. label: '宽',
  242. },
  243. {
  244. value: 'height',
  245. label: '高',
  246. },
  247. {
  248. value: 'visible',
  249. label: '显示',
  250. },
  251. {
  252. value: 'text',
  253. label: '文字',
  254. },
  255. {
  256. value: 'progress',
  257. label: '进度',
  258. },
  259. {
  260. value: 'showChild',
  261. label: '状态',
  262. },
  263. {
  264. value: 'rotate',
  265. label: '旋转',
  266. },
  267. ]);
  268. const operatorOptions = [
  269. { label: '=', value: '=' },
  270. { label: '!=', value: '!=' },
  271. { label: '>', value: '>' },
  272. { label: '<', value: '<' },
  273. { label: '>=', value: '>=' },
  274. { label: '<=', value: '<=' },
  275. { label: '包含', value: '[)' },
  276. { label: '不包含', value: '![)' },
  277. ];
  278. </script>
  279. <style lang="postcss" scoped>
  280. .props {
  281. .form-item {
  282. :deep(.t-radio-group .t-radio) {
  283. margin-right: 10px;
  284. .t-radio__label {
  285. margin-left: 4px;
  286. }
  287. }
  288. }
  289. .form-item-valueType {
  290. /* :deep(.t-input) {
  291. padding: 0px;
  292. } */
  293. }
  294. .banner {
  295. /* background-color: var(--color-background-input); */
  296. /* padding: 0 12px; */
  297. }
  298. }
  299. </style>